On Monday, 16 October 2006 20:21, Dawid Ciezarkiewicz wrote:
> This patch is little thinner then the previous one.

I'm sorry for that. I've just ... nevermind. Here goes the patch.

Should I post patch for ifenslave here, too?



diff -Nur linux-2.6.17.orig/Documentation/networking/bonding.txt 
linux-2.6.17/Documentation/networking/bonding.txt
--- linux-2.6.17.orig/Documentation/networking/bonding.txt      2006-06-18 
03:49:35.000000000 +0200
+++ linux-2.6.17/Documentation/networking/bonding.txt   2006-07-28 
15:47:55.000000000 +0200
@@ -398,6 +398,19 @@
                swapped with the new curr_active_slave that was
                chosen.
 
+       weighted-rr or 7
+
+               Weighted round-robin bonding. In this mode bonding
+               interface will use weights assigned to it's slaves.
+
+               Each slave can have weight assigned via ioctl (ifenslave).
+               These values will be used at the start of each "cycle".
+               Each slave will have token counter restored to it's weight.
+               Then using round-robin mechanism those tokens are "used"
+               to pay for emitted frames. When all token counters are
+               zeroed - new "cycle" begins.
+               
+
 primary
 
        A string (eth0, eth2, etc) specifying which slave is the
diff -Nur linux-2.6.17.orig/drivers/net/bonding/bond_main.c 
linux-2.6.17/drivers/net/bonding/bond_main.c
--- linux-2.6.17.orig/drivers/net/bonding/bond_main.c   2006-06-18 
03:49:35.000000000 +0200
+++ linux-2.6.17/drivers/net/bonding/bond_main.c        2006-07-28 
15:31:44.000000000 +0200
@@ -115,7 +115,7 @@
 MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
                       "1 for active-backup, 2 for balance-xor, "
                       "3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
-                      "6 for balance-alb");
+                      "6 for balance-alb, 7 for weighted-rr");
 module_param(primary, charp, 0);
 MODULE_PARM_DESC(primary, "Primary network device to use");
 module_param(lacp_rate, charp, 0);
@@ -162,6 +162,7 @@
 {      "802.3ad",              BOND_MODE_8023AD},
 {      "balance-tlb",          BOND_MODE_TLB},
 {      "balance-alb",          BOND_MODE_ALB},
+{      "weighted-rr",          BOND_MODE_WEIGHTED_RR},
 {      NULL,                   -1},
 };
 
@@ -194,6 +195,8 @@
                return "transmit load balancing";
        case BOND_MODE_ALB:
                return "adaptive load balancing";
+       case BOND_MODE_WEIGHTED_RR:
+               return "weighted round robin (weighted-rr)";
        default:
                return "unknown";
        }
@@ -1198,6 +1201,24 @@
        return 0;
 }
 
+int bond_set_weight(struct net_device *bond_dev, struct net_device *slave_dev,
+               u16 weight)
+{
+       struct slave* slave;
+       slave = bond_get_slave_by_dev(bond_dev->priv, slave_dev);
+       if (!slave) {
+               return -EINVAL;
+       }
+
+       slave->weight = weight;
+
+       if (weight) {
+               slave->link = BOND_LINK_UP;
+               slave->state = BOND_STATE_ACTIVE;
+       }
+       return 0;
+}
+
 #define BOND_INTERSECT_FEATURES \
        (NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM|\
        NETIF_F_TSO|NETIF_F_UFO)
@@ -1336,6 +1352,9 @@
         */
        new_slave->original_flags = slave_dev->flags;
 
+       /* slave default weight = 1 */
+       new_slave->weight = 1;
+
        /*
         * Save slave's original ("permanent") mac address for modes
         * that need it, and for restoring it upon release, and then
@@ -3601,7 +3620,10 @@
        }
 
        down_write(&(bonding_rwsem));
-       slave_dev = dev_get_by_name(ifr->ifr_slave);
+       if (cmd != SIOCBONDSETWEIGHT)
+               slave_dev = dev_get_by_name(ifr->ifr_slave);
+       else
+               slave_dev = dev_get_by_name(ifr->ifr_weight_slave);
 
        dprintk("slave_dev=%p: \n", slave_dev);
 
@@ -3626,6 +3648,9 @@
                case SIOCBONDCHANGEACTIVE:
                        res = bond_ioctl_change_active(bond_dev, slave_dev);
                        break;
+               case SIOCBONDSETWEIGHT:
+                       res = bond_set_weight(bond_dev, slave_dev, 
ifr->ifr_weight_weight);
+                       break;
                default:
                        res = -EOPNOTSUPP;
                }
@@ -3881,6 +3906,67 @@
        return 0;
 }
 
+static int bond_xmit_weighted_rr(struct sk_buff *skb, struct net_device 
*bond_dev)
+{
+       struct bonding *bond = bond_dev->priv;
+       struct slave *slave, *start_at;
+       int i;
+       int res = 1;
+       int were_weight_tokens_recharged = 0;
+
+       read_lock(&bond->lock);
+
+       if (!BOND_IS_OK(bond)) {
+               goto out;
+       }
+
+       read_lock(&bond->curr_slave_lock);
+       slave = start_at = bond->curr_active_slave;
+       read_unlock(&bond->curr_slave_lock);
+
+       if (!slave) {
+               goto out;
+       }
+
+try_send:
+       bond_for_each_slave_from(bond, slave, i, start_at) {
+               if (IS_UP(slave->dev) &&
+                   (slave->weight_tokens > 0) &&
+                       (slave->link == BOND_LINK_UP) &&
+                   (slave->state == BOND_STATE_ACTIVE)) {
+                       
+                       res = bond_dev_queue_xmit(bond, skb, slave->dev);
+                       (slave->weight_tokens)--;
+                       write_lock(&bond->curr_slave_lock);
+                       bond->curr_active_slave = slave->next;
+                       write_unlock(&bond->curr_slave_lock);
+
+                       goto out;
+               }
+       }
+       
+       if (were_weight_tokens_recharged == 0) {
+               read_lock(&bond->curr_slave_lock);
+               slave = start_at = bond->curr_active_slave;
+               read_unlock(&bond->curr_slave_lock);
+
+               bond_for_each_slave_from(bond, slave, i, start_at) {
+                       slave->weight_tokens = slave->weight;
+               }
+
+               were_weight_tokens_recharged = 1;
+               goto try_send;
+       }
+
+out:
+       if (res) {
+               /* no suitable interface, frame not sent */
+               dev_kfree_skb(skb);
+       }
+       read_unlock(&bond->lock);
+       return 0;
+}
+
 static void bond_activebackup_xmit_copy(struct sk_buff *skb,
                                         struct bonding *bond,
                                         struct slave *slave)
@@ -4088,6 +4174,9 @@
        case BOND_MODE_ROUNDROBIN:
                bond_dev->hard_start_xmit = bond_xmit_roundrobin;
                break;
+       case BOND_MODE_WEIGHTED_RR:
+               bond_dev->hard_start_xmit = bond_xmit_weighted_rr;
+               break;
        case BOND_MODE_ACTIVEBACKUP:
                bond_dev->hard_start_xmit = bond_xmit_activebackup;
                break;
diff -Nur linux-2.6.17.orig/drivers/net/bonding/bond_sysfs.c 
linux-2.6.17/drivers/net/bonding/bond_sysfs.c
--- linux-2.6.17.orig/drivers/net/bonding/bond_sysfs.c  2006-06-18 
03:49:35.000000000 +0200
+++ linux-2.6.17/drivers/net/bonding/bond_sysfs.c       2006-07-28 
15:25:11.000000000 +0200
@@ -241,10 +241,14 @@
                        res += sprintf(buf + res, "++more++");
                        break;
                }
-               res += sprintf(buf + res, "%s ", slave->dev->name);
+               if (bond->params.mode == BOND_MODE_WEIGHTED_RR) {
+                       res += sprintf(buf + res, "%s %d\n", slave->dev->name,
+                                       slave->weight);
+               } else {
+                       res += sprintf(buf + res, "%s\n", slave->dev->name);
+               }
        }
        read_unlock_bh(&bond->lock);
-       res += sprintf(buf + res, "\n");
        res++;
        return res;
 }
diff -Nur linux-2.6.17.orig/drivers/net/bonding/bonding.h 
linux-2.6.17/drivers/net/bonding/bonding.h
--- linux-2.6.17.orig/drivers/net/bonding/bonding.h     2006-06-18 
03:49:35.000000000 +0200
+++ linux-2.6.17/drivers/net/bonding/bonding.h  2006-07-28 15:25:11.000000000 
+0200
@@ -150,6 +150,8 @@
        struct slave *next;
        struct slave *prev;
        s16    delay;
+       u16    weight_tokens;
+       u16    weight;
        u32    jiffies;
        s8     link;    /* one of BOND_LINK_XXXX */
        s8     state;   /* one of BOND_STATE_XXXX */
diff -Nur linux-2.6.17.orig/include/linux/if.h linux-2.6.17/include/linux/if.h
--- linux-2.6.17.orig/include/linux/if.h        2006-06-18 03:49:35.000000000 
+0200
+++ linux-2.6.17/include/linux/if.h     2006-07-28 15:25:11.000000000 +0200
@@ -172,6 +172,11 @@
                char    ifru_newname[IFNAMSIZ];
                void __user *   ifru_data;
                struct  if_settings ifru_settings;
+               struct {
+                       __u16 weight;
+                       char slave[IFNAMSIZ];   
+               } ifru_weight;
+
        } ifr_ifru;
 };
 
@@ -180,6 +185,8 @@
 #define        ifr_addr        ifr_ifru.ifru_addr      /* address              
*/
 #define        ifr_dstaddr     ifr_ifru.ifru_dstaddr   /* other end of p-p lnk 
*/
 #define        ifr_broadaddr   ifr_ifru.ifru_broadaddr /* broadcast address    
*/
+#define        ifr_weight_weight ifr_ifru.ifru_weight.weight /* bonding 
weight*/
+#define        ifr_weight_slave  ifr_ifru.ifru_weight.slave  /* bonding weight 
slave */
 #define        ifr_netmask     ifr_ifru.ifru_netmask   /* interface net mask   
*/
 #define        ifr_flags       ifr_ifru.ifru_flags     /* flags                
*/
 #define        ifr_metric      ifr_ifru.ifru_ivalue    /* metric               
*/
diff -Nur linux-2.6.17.orig/include/linux/if_bonding.h 
linux-2.6.17/include/linux/if_bonding.h
--- linux-2.6.17.orig/include/linux/if_bonding.h        2006-06-18 
03:49:35.000000000 +0200
+++ linux-2.6.17/include/linux/if_bonding.h     2006-07-28 15:25:11.000000000 
+0200
@@ -70,6 +70,7 @@
 #define BOND_MODE_8023AD        4
 #define BOND_MODE_TLB           5
 #define BOND_MODE_ALB          6 /* TLB + RLB (receive load balancing) */
+#define BOND_MODE_WEIGHTED_RR   7
 
 /* each slave's link has 4 states */
 #define BOND_LINK_UP    0           /* link is up and running */
diff -Nur linux-2.6.17.orig/include/linux/sockios.h 
linux-2.6.17/include/linux/sockios.h
--- linux-2.6.17.orig/include/linux/sockios.h   2006-06-18 03:49:35.000000000 
+0200
+++ linux-2.6.17/include/linux/sockios.h        2006-07-28 15:25:11.000000000 
+0200
@@ -115,6 +115,7 @@
 #define SIOCBONDSLAVEINFOQUERY 0x8993   /* rtn info about slave state   */
 #define SIOCBONDINFOQUERY      0x8994  /* rtn info about bond state    */
 #define SIOCBONDCHANGEACTIVE   0x8995   /* update to a new active slave */
+#define SIOCBONDSETWEIGHT      0x899e   /* update weight */
                        
 /* bridge calls */
 #define SIOCBRADDBR     0x89a0         /* create new bridge device     */
diff -Nur linux-2.6.17.orig/net/core/dev.c linux-2.6.17/net/core/dev.c
--- linux-2.6.17.orig/net/core/dev.c    2006-06-18 03:49:35.000000000 +0200
+++ linux-2.6.17/net/core/dev.c 2006-07-28 15:25:11.000000000 +0200
@@ -2495,6 +2495,7 @@
                            cmd <= SIOCDEVPRIVATE + 15) ||
                            cmd == SIOCBONDENSLAVE ||
                            cmd == SIOCBONDRELEASE ||
+                           cmd == SIOCBONDSETWEIGHT ||
                            cmd == SIOCBONDSETHWADDR ||
                            cmd == SIOCBONDSLAVEINFOQUERY ||
                            cmd == SIOCBONDINFOQUERY ||
@@ -2656,6 +2657,7 @@
                case SIOCBONDRELEASE:
                case SIOCBONDSETHWADDR:
                case SIOCBONDCHANGEACTIVE:
+               case SIOCBONDSETWEIGHT:
                case SIOCBRADDIF:
                case SIOCBRDELIF:
                        if (!capable(CAP_NET_ADMIN))

-
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to