Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
programmation kernel
Envoyé par: rufa

Bonjour, j'ai compilé un programme kernel qui affiche hello word:

hello.c
* Copyright (C) 1998 by Ori Pomerantz
*
* "Hello, world" - the kernel module version.
*/
/* The necessary header files */
/* Standard in kernel modules */
#include <linux/kernel.h> /* We’re doing kernel work */
#include <linux/module.h> /* Specifically, a module */
/* Deal with CONFIG_MODVERSIONS */
#if CONFIG_MODVERSIONS==1
#define MODVERSIONS
#include <linux/modversions.h>
#endif
/* Initialize the module */
int init_module()
{
printk("Hello, world - this is the kernel speaking\n");
/* If we return a non zero value, it means that
* init_module failed and the kernel module
* can’t be loaded */
return 0;
}
/* Cleanup - undid whatever init_module did */
void cleanup_module()
{
printk("Short is the life of a kernel module\n");
}

les erreurs suivantes son apparus:


abdelkader@abdelkader:~$ make hello
cc hello.c -o hello
In file included from /usr/include/asm-i486/local.h:4,


from /usr/include/asm/local.h:8,


from /usr/include/linux/module.h:20,


from hello.c:2:
/usr/include/linux/percpu.h: In function ‘__alloc_percpu’:
/usr/include/linux/percpu.h:44: error: ‘GFP_KERNEL’ undeclared (first use in this function)
/usr/include/linux/percpu.h:44: error: (Each undeclared identifier is reported only once
/usr/include/linux/percpu.h:44: error: for each function it appears in.)
In file included from /usr/include/asm/module.h:8,

from /usr/include/linux/module.h:22,

from hello.c:2:
/usr/include/asm-i486/module.h:60:2: error: #error unknown processor family
In file included
from hello.c:2:
/usr/include/linux/module.h: At top level:
/usr/include/linux/module.h:49: error: field ‘attr’ has incomplete type
/usr/include/linux/module.h:60: error: field ‘kobj’ has incomplete type
make: *** [hello] Erreur 1

le fichier make file :

# Makefile for a basic kernel module
CC=gcc
MODCFLAGS := -Wall -DMODULE -D__KERNEL__ -DLINUX
hello.o: hello.c /usr/include/linux/version.h
$(CC) $(MODCFLAGS) -c hello.c
echo insmod hello.o to turn it on
echo rmmod hello to turn if off
echo
echo X and kernel programming do not mix.
echo Do the insmod and rmmod from outside X.


la distribution est debian version 4.0.
svp je veut comprend les erreurs pour que je puisse les résoudre.

Poste le Friday 31 October 2008 21:07:01
Répondre     Citer    
Re: programmation kernel
Envoyé par: rufa


salut,on ma dit le kernel a beacoup changer depuis 1999 (la date de ce programme)alors j'ai compilé avec la version du kernel 2.6 "[www.tldp.org];
le programme est :

/*
* hello-1.c - The simplest kernel module.
*/
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */

int init_module(void)
{
printk(KERN_INFO "Hello world 1.n");

/*
* A non 0 return means init_module failed; module can't be loaded.
*/
return 0;
}

void cleanup_module(void)
{
printk(KERN_INFO "Goodbye world 1.n");
}
mais dans la compilation avec make les erreurs:
cc hello.c -o hello
In

file included from /usr/include/asm-i486/local.h:4,

from /usr/include/asm/local.h:8,

from /usr/include/linux/module.h:20,

from hello.c:2:
/usr/include/linux/percpu.h: In function ‘__alloc_percpu’:

/usr/include/linux/percpu.h:44: error: ‘GFP_KERNEL’ undeclared (first use in this function)
/usr/include/linux/percpu.h:44: error: (Each undeclared identifier is reported only once
/usr/include/linux/percpu.h:44: error: for each function it appears in.)

In file included from
/usr/include/asm/module.h:8,

from /usr/include/linux/module.h:22,

from hello.c:2:
/usr/include/asm-i486/module.h:60:2: error: #error unknown processor family
In file included from hello.c:2:
/usr/include/linux/module.h: At top level:

/usr/include/linux/module.h:49: error: field ‘attr’ has incomplete type

/usr/include/linux/module.h:60: error: field ‘kobj’ has incomplete type

hello.c: In function ‘init_module’:
hello.c:6: error: ‘KERN_INFO’ undeclared (first use in this function)

hello.c:6: error: expected ‘)’ before string constant

hello.c: In function ‘cleanup_module’:

hello.c:12: error: ‘KERN_INFO’ undeclared (first use in this function)

hello.c:12: error: expected ‘)’ before string constant

hello.c:13:2: warning: no newline at end of file

make: *** [hello] Erreur 1

alors j'ai supprimé KERN INFO alors le résultat est :

cc hello.c -o hello

In file included from
/usr/include/asm-i486/local.h:4,

from /usr/include/asm/local.h:8,
from /usr/include/linux/module.h:20,
from hello.c:2:
/usr/include/linux/percpu.h: In function ‘__alloc_percpu’:

/usr/include/linux/percpu.h:44: error: ‘GFP_KERNEL’ undeclared (first use in this function)
/usr/include/linux/percpu.h:44: error: (Each undeclared identifier is reported only once
/usr/include/linux/percpu.h:44: error: for each function it appears in.)

In file included from
/usr/include/asm/module.h:8,

from /usr/include/linux/module.h:22,

from hello.c:2:
/usr/include/asm-i486/module.h:60:2: error: #error unknown processor family

In file included from
hello.c:2:
/usr/include/linux/module.h: At top level:

/usr/include/linux/module.h:49: error: field ‘attr’ has incomplete type

/usr/include/linux/module.h:60: error: field ‘kobj’ has incomplete type

hello.c:13:2: warning: no newline at end of file

make: *** [hello] Erreur 1

le fichier Makefile est :
obj-m += hello-1.o

all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

svp aidai moi c'est pour mon projet de fin d'étude,merci d'avace.

Poste le Friday 31 October 2008 22:36:26
Répondre     Citer    
Re: programmation kernel
Envoyé par: rufa

pour: hello.c:13:2: warning: no newline at end of file
c'est résolu,il suffit d'aller a la dernière ligne du programme et d'appuyer sur entre,il reste le plus difficile.

Poste le Friday 31 October 2008 23:46:57
Répondre     Citer    
Re: programmation kernel

Citation
rufa
svp aidez moi c'est pour mon projet de fin d'études; merci d'avance
.

Primo, ta question n'est pas spécifique à Debian: elle serait mieux dans la section "Developpement"

Un module noyau ne se compile pas directement avec la commande cc. En googlant sur "writing linux module 2.6" j'obtiens ceci

Et à mon avis, il te manque des bases pour espérer toucher au noyau. En particulier, il te faut bien connaitre le langage C et comment on compile avec make (et vu la teneur de tes questions tu ne connais ni l'un ni l'autre).

Je te conseille donc:

* De lire plusieurs livres et documents avant tout (sur C, la compilation sous Linux, l'organisation du noyau, les modules)

* D'abord d'apprendre le C en codant quelques applications linuxiennes (pas des modules noyaux). Utilises donc un système de version (subversion par exemple), un bon éditeur (emacs).

* Ensuite d'apprendre à compiler des vrais modules du noyaux (par exemple en compilant un pilote spécifique)

* Enfin, d'écrire ton premier module; n'oublies pas de faire la commande sync juste avant de le charger. Vu le niveau de tes questions, tu planteras ton noyau assez souvent, et ton système avec. N'oublies pas de sauvegarder les données qui te sont chères, tu risques de les perdre autrement.

Il te manque donc des semaines (voire des mois) de travail intensif.


PS. Dis nous dans quelle école ou faculté tu étudies. Car "ça craint" de voir des élèves en fin d'études avec un niveau si faible (même en orthographe), et incapable de chercher à se documenter par eux même! (J'ai probablement l'âge de ton père, et la qualification pour être ton enseignant).

----

Basile STARYNKEVITCH

Membre de l'APRIL « promouvoir et défendre le logiciel libre » - adhérez vous aussi à l'APRIL!

Projet logiciel libre: RefPerSys

Poste le Saturday 1 November 2008 08:03:31
Répondre     Citer    
Re: programmation kernel
Envoyé par: rufa

bonjours,tout ce que vous avez dit est vrai,je suis un étudiant en 5 année ingénieur(université d'Oran Algérie alors la ça saute au yeux que de la théorie ),j'ai l'habitude de programmer mais sous windows (dev c++),j'ai coder beaucoup de programmes comme "dijkstra" en trois ieme année et une application de la gestion de la bibliothèque avec le builder C++ en 4 ieme année mais sous linux c'est différent surtout les commandes,je dois le reconnaitre: je suis très loin du niveau d'un future ingénieur (l'anglais aussi me pose des problèmes)et je n'ai pas de honte à le dire puisque c'est la vérité,j'ai posé cette question dans la section Debian pour que les gents sachent que ma distribution est Debian mais c'est vraie j'aurais pu mettre en dernière ligne ma configuration dans la section développement.
je suis un étudiant très sérieux qui aime travailler dure.
Alors svp vous pouvez m'aider dans mon projet.Je vous promet d'étre sérieux et je vous serais très reconnaissant.
la documentation que mon encadreur ma donnée est la suivante:
"[ldp.org]; pour les modules kernel.
"[www.linuxfoundation.org]; pour le net bonding.

Poste le Saturday 1 November 2008 11:49:52
Répondre     Citer    
Re: programmation kernel

Il te faut lire la documentation (celle que j'ai indiquée, et d'autres). La bibliothèque de ton université a peut-être d'excellents livres.

je n'ai pas le temps de réécrire une documentation pour toi.


----

Basile STARYNKEVITCH

Membre de l'APRIL « promouvoir et défendre le logiciel libre » - adhérez vous aussi à l'APRIL!

Projet logiciel libre: RefPerSys

Poste le Saturday 1 November 2008 11:56:33
Répondre     Citer    
Re: programmation kernel
Envoyé par: rufa

bonjours,merci beaucoup pour les conseils,moi ce que je veut savoir "si je peut vous posez des questions qui peut me bloquer dans le future"?

Poste le Saturday 1 November 2008 14:59:25
Répondre     Citer    
Re: programmation kernel

Rien ni personne n'interdit de poser des questions sur Linux ici. Ce forum est même fait pour ça.

Mais rien ni personne n'oblige à y répondre, et en ce qui me concerne, je préfère répondre à des gens qui ont déjà travaillé leurs questions.

----

Basile STARYNKEVITCH

Membre de l'APRIL « promouvoir et défendre le logiciel libre » - adhérez vous aussi à l'APRIL!

Projet logiciel libre: RefPerSys

Poste le Saturday 1 November 2008 15:02:39
Répondre     Citer    
Re: programmation kernel
Envoyé par: rufa

merci.

Poste le Saturday 1 November 2008 16:37:50
Répondre     Citer    
Re: programmation kernel
Envoyé par: rufa

Bonjour, bon voila:
les erreurs qu'il affiche c'est qu'il n'arrive pas a déterminer le chemin vers les bibliothèques comme (modume.h ou kernel.h) alors il faut recompiler le noyau ensuite recompiler le programme "Hello" ou le module bonding.
j'espère que ça va aider quelqu'un dans le future.
Merci a vous.

Poste le Saturday 28 March 2009 08:28:00
Répondre     Citer    
Re: programmation kernel
Envoyé par: rufa

Bonjour, voila la solution, sachent qu'il faut ajouter "#define BOND_MODE_NOUVEAU 7" dans le fichier if_bonding.h et le tableau "bond_parm_tbl bond_ethx_tbl[]" dans le fichier bond_sysfs.c et recompiler le tous.

Remarque: j'ai enlevé plusieurs parties, j'ai laissé que cellle modifiabes pour que ça rentre.


/*
* originally based on the dummy device.
*
* Copyright 1999, Thomas Davis, tadavis@lbl.gov.
* Licensed under the GPL. Based on dummy.c, and eql.c devices.
*
* bonding.c: an Ethernet Bonding driver
*
* This is useful to talk to a Cisco EtherChannel compatible equipment:
* Cisco 5500
* Sun Trunking (Solaris)
* Alteon AceDirector Trunks
* Linux Bonding
* and probably many L2 switches ...
*
* How it works:
* ifconfig bond0 ipaddress netmask up
* will setup a network device, with an ip address. No mac address
* will be assigned at this time. The hw mac address will come from
* the first slave bonded to the channel. All slaves will then use
* this hw mac address.
*
* ifconfig bond0 down
* will release all slaves, marking them as down.
*
* ifenslave bond0 eth0
* will attach eth0 to bond0 as a slave. eth0 hw mac address will either
* a: be used as initial mac address
* b: if a hw mac address already is there, eth0's hw mac address
* will then be set from bond0.
*
*/

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <net/ip.h>
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/init.h>
#include <linux/timer.h>
#include <linux/socket.h>
#include <linux/ctype.h>
#include <linux/inet.h>
#include <linux/bitops.h>
#include <asm/system.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <asm/uaccess.h>
#include <linux/errno.h>
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/igmp.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
#include <net/sock.h>
#include <linux/rtnetlink.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/smp.h>
#include <linux/if_ether.h>
#include <net/arp.h>
#include <linux/mii.h>
#include <linux/ethtool.h>
#include <linux/if_vlan.h>
#include <linux/if_bonding.h>
#include <linux/jiffies.h>
#include <net/route.h>
#include <net/net_namespace.h>
#include "bonding.h"
#include "bond_3ad.h"
#include "bond_alb.h"

/*---------------------------- Module parameters ----------------------------*/

/* monitor all links that often (in milliseconds). <=0 disables monitoring */
#define BOND_LINK_MON_INTERV 0
#define BOND_LINK_ARP_INTERV 0

static int max_bonds = BOND_DEFAULT_MAX_BONDS;
static int num_grat_arp = 1;
static int num_unsol_na = 1;
static int miimon = BOND_LINK_MON_INTERV;
static int updelay = 0;
static int downdelay = 0;
static int use_carrier = 1;
static char *mode = NULL;
static char *primary = NULL;
static char *lacp_rate = NULL;
static char *ad_select = NULL;
static char *xmit_hash_policy = NULL;
static int arp_interval = BOND_LINK_ARP_INTERV;
static char *arp_ip_target[BOND_MAX_ARP_TARGETS] = { NULL, };
static char *arp_validate = NULL;
static char *fail_over_mac = NULL;
struct bond_params bonding_defaults;

/**************modificationnnnnnnnnnnnn*******************/

static char *eth0 = NULL;
static char *eth1 = NULL;
static char *eth2 = NULL;
static char *eth3 = NULL;
static char *eth4 = NULL;
static char *eth5 = NULL;
static char *eth6 = NULL;
static char *eth7 = NULL;
static char *eth8 = NULL;
static char *eth9 = NULL;
static char *eth10 = NULL;
static char *eth11 = NULL;
static char *eth12 = NULL;
static char *eth13 = NULL;
static char *eth14 = NULL;
static char *eth15 = NULL;

/**************modificationnnnnnnnnnnnn*******************/

module_param(max_bonds, int, 0);
MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
module_param(num_grat_arp, int, 0644);
MODULE_PARM_DESC(num_grat_arp, "Number of gratuitous ARP packets to send on failover event");
module_param(num_unsol_na, int, 0644);
MODULE_PARM_DESC(num_unsol_na, "Number of unsolicited IPv6 Neighbor Advertisements packets to send on failover event");
module_param(miimon, int, 0);
MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
module_param(updelay, int, 0);
MODULE_PARM_DESC(updelay, "Delay before considering link up, in milliseconds");
module_param(downdelay, int, 0);
MODULE_PARM_DESC(downdelay, "Delay before considering link down, "
"in milliseconds");
module_param(use_carrier, int, 0);
MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
"0 for off, 1 for on (default)");
module_param(mode, charp, 0);
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");
module_param(primary, charp, 0);
MODULE_PARM_DESC(primary, "Primary network device to use");
module_param(lacp_rate, charp, 0);
MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
"(slow/fast)");
module_param(ad_select, charp, 0);
MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic: stable (0, default), bandwidth (1), count (2)");
module_param(xmit_hash_policy, charp, 0);
MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
", 1 for layer 3+4");
module_param(arp_interval, int, 0);
MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
module_param_array(arp_ip_target, charp, NULL, 0);
MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
module_param(arp_validate, charp, 0);
MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
module_param(fail_over_mac, charp, 0);
MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow");


/**************modificationnnnnnnnnnnnn*******************/

module_param(eth0, charp, 0);
MODULE_PARM_DESC(eth0, "l'interface eth0");
module_param(eth1, charp, 0);
MODULE_PARM_DESC(eth1, "l'interface eth1");
module_param(eth2, charp, 0);
MODULE_PARM_DESC(eth2, "l'interface eth2");
module_param(eth3, charp, 0);
MODULE_PARM_DESC(eth3, "l'interface eth3");
module_param(eth4, charp, 0);
MODULE_PARM_DESC(eth4, "l'interface eth4");
module_param(eth5, charp, 0);
MODULE_PARM_DESC(eth5, "l'interface eth5");
module_param(eth6, charp, 0);
MODULE_PARM_DESC(eth6, "l'interface eth6");
module_param(eth7, charp, 0);
MODULE_PARM_DESC(eth7, "l'interface eth7");
module_param(eth8, charp, 0);
MODULE_PARM_DESC(eth8, "l'interface eth8");
module_param(eth9, charp, 0);
MODULE_PARM_DESC(eth9, "l'interface eth9");
module_param(eth10, charp, 0);
MODULE_PARM_DESC(eth10, "l'interface eth10");
module_param(eth11, charp, 0);
MODULE_PARM_DESC(eth11, "l'interface eth11");
module_param(eth12, charp, 0);
MODULE_PARM_DESC(eth12, "l'interface eth12");
module_param(eth13, charp, 0);
MODULE_PARM_DESC(eth13, "l'interface eth13");
module_param(eth14, charp, 0);
MODULE_PARM_DESC(eth14, "l'interface eth14");
module_param(eth15, charp, 0);
MODULE_PARM_DESC(eth15, "l'interface eth15");

/*----------------------------- Global variables ----------------------------*/

static const char * const version =
DRV_DESCRIPTION ": v" DRV_VERSION " (" DRV_RELDATE ")\n";

LIST_HEAD(bond_dev_list);

#ifdef CONFIG_PROC_FS
static struct proc_dir_entry *bond_proc_dir = NULL;
#endif

static __be32 arp_target[BOND_MAX_ARP_TARGETS] = { 0, } ;
static int arp_ip_count = 0;
static int bond_mode = BOND_MODE_ROUNDROBIN;
static int xmit_hashtype= BOND_XMIT_POLICY_LAYER2;
static int lacp_fast = 0;
/*******************************modificationnnnnnnnnnn****************************/
u32 param_eth0 = 0;
u32 param_eth1 = 0;
u32 param_eth2 = 0;
u32 param_eth3 = 0;
u32 param_eth4 = 0;
u32 param_eth5 = 0;
u32 param_eth6 = 0;
u32 param_eth7 = 0;
u32 param_eth8 = 0;
u32 param_eth9 = 0;
u32 param_eth10 = 0;
u32 param_eth11 = 0;
u32 param_eth12 = 0;
u32 param_eth13 = 0;
u32 param_eth14 = 0;
u32 param_eth15 = 0;
int j = -1;
/*******************************modificationnnnnnnnnnn****************************/
const struct bond_parm_tbl bond_lacp_tbl[] = {
{ "slow", AD_LACP_SLOW},
{ "fast", AD_LACP_FAST},
{ NULL, -1},
};

const struct bond_parm_tbl bond_mode_tbl[] = {
{ "balance-rr", BOND_MODE_ROUNDROBIN},
{ "active-backup", BOND_MODE_ACTIVEBACKUP},
{ "balance-xor", BOND_MODE_XOR},
{ "broadcast", BOND_MODE_BROADCAST},
{ "802.3ad", BOND_MODE_8023AD},
{ "balance-tlb", BOND_MODE_TLB},
{ "balance-alb", BOND_MODE_ALB},
{ "nouveau-mode", BOND_MODE_NOUVEAU}, /**********************modification**************************/
{ NULL, -1},
};

const struct bond_parm_tbl xmit_hashtype_tbl[] = {
{ "layer2", BOND_XMIT_POLICY_LAYER2},
{ "layer3+4", BOND_XMIT_POLICY_LAYER34},
{ "layer2+3", BOND_XMIT_POLICY_LAYER23},
{ NULL, -1},
};

const struct bond_parm_tbl arp_validate_tbl[] = {
{ "none", BOND_ARP_VALIDATE_NONE},
{ "active", BOND_ARP_VALIDATE_ACTIVE},
{ "backup", BOND_ARP_VALIDATE_BACKUP},
{ "all", BOND_ARP_VALIDATE_ALL},
{ NULL, -1},
};

const struct bond_parm_tbl fail_over_mac_tbl[] = {
{ "none", BOND_FOM_NONE},
{ "active", BOND_FOM_ACTIVE},
{ "follow", BOND_FOM_FOLLOW},
{ NULL, -1},
};

struct bond_parm_tbl ad_select_tbl[] = {
{ "stable", BOND_AD_STABLE},
{ "bandwidth", BOND_AD_BANDWIDTH},
{ "count", BOND_AD_COUNT},
{ NULL, -1},
};

struct bond_parm_tbl bond_ethx_tbl[] = {
};


/*-------------------------- Forward declarations ---------------------------*/

static void bond_send_gratuitous_arp(struct bonding *bond);
static void bond_deinit(struct net_device *bond_dev);

/*---------------------------- General routines -----------------------------*/

static const char *bond_mode_name(int mode)
{
static const char *names[] = {
[BOND_MODE_ROUNDROBIN] = "load balancing (round-robin)",
[BOND_MODE_ACTIVEBACKUP] = "fault-tolerance (active-backup)",
[BOND_MODE_XOR] = "load balancing (xor)",
[BOND_MODE_BROADCAST] = "fault-tolerance (broadcast)",
[BOND_MODE_8023AD]= "IEEE 802.3ad Dynamic link aggregation",
[BOND_MODE_TLB] = "transmit load balancing",
[BOND_MODE_ALB] = "adaptive load balancing",
[BOND_MODE_NOUVEAU] = "nouveau-mode", /**************************modification*************************/
};

if (mode < 0 || mode > BOND_MODE_ALcool smiley
return "unknown";

return names[mode];
}




static int bond_xmit_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *start_at;
int i, slave_no, res = 1;

read_lock(&bond->lock);

if (!BOND_IS_OK(bond)) {
goto out;
}

/*
* Concurrent TX may collide on rr_tx_counter; we accept that
* as being rare enough not to justify using an atomic op here
*/
slave_no = bond->rr_tx_counter++ % bond->slave_cnt;

bond_for_each_slave(bond, slave, i) {
slave_no--;
if (slave_no < 0) {
break;
}
}

start_at = slave;
bond_for_each_slave_from(bond, slave, i, start_at) {
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
(slave->state == BOND_STATE_ACTIVE)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
break;
}
}

out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
read_unlock(&bond->lock);
return 0;
}


/*
* in active-backup mode, we know that bond->curr_active_slave is always valid if
* the bond has a usable interface.
*/

/*****************************modificationnnnnnnnnnn*********************************/

static int bond_xmit_my_roundrobin(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *start_at;
int i, slave_no, res = 1, var, k;

read_lock(&bond->lock);

if (!BOND_IS_OK(bond)) {
goto out;
}

/*
* Concurrent TX may collide on rr_tx_counter; we accept that
* as being rare enough not to justify using an atomic op here
*/
slave_no = bond->rr_tx_counter++ % bond->slave_cnt;

bond_for_each_slave(bond, slave, i) {
slave_no--;
if (slave_no < 0) {
break;
}
}

start_at = slave;

bond_for_each_slave_from(bond, slave, i, start_at) {

printk("\n salam, l'interface présente dans la boucle bond_for_eache_slave est: %s \n", slave->dev->name);
var=0;
for(k=0; k<=j; k++){
if(strcmp(slave->dev->name, bond_ethx_tbl[k].modename) == 0 ){
printk("\n l'interface réserver est:%s, et son marquage est:%d \n", slave->dev->name, bond_ethx_tbl[k].mode);
var=1;
}
}
printk("\n la valeure de var est:%d\n", var);
if(var == 0) {

if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
(slave->state == BOND_STATE_ACTIVE)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
break;
}
}
}

out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
read_unlock(&bond->lock);
return 0;
}


static int bond_xmit_nouveau(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave;
struct net_device *bond_dev1 = bond_dev;
int i,res;
read_lock(&bond->lock);

if (!BOND_IS_OK(bond)) {
goto out;
}
printk("\n salam, le marquage de nfmark est:%u\n", skb->mark);

if(eth0)
{
if( skb->mark == param_eth0 )
{
printk("\n salam, l'interface eth00000000000000000000");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth0") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth1)
{
if( skb->mark == param_eth1 )
{
printk("\n salam, l'intetrface eth11111111111111111");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth1") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth2)
{
if( skb->mark == param_eth2 )
{
printk("\n salam, l'intetrface eth2222222222222222");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth2") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth3)
{
if( skb->mark == param_eth3 )
{
printk("\n salam, l'intetrface eth333333333333333");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth3") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth4)
{
if( skb->mark == param_eth4 )
{
printk("\n salam, l'intetrface eth44444444444444");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth4") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth5)
{
if( skb->mark == param_eth5 )
{
printk("\n salam, l'intetrface eth55555555555555");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth5") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth6)
{
if( skb->mark == param_eth6 )
{
printk("\n salam, l'intetrface eth66666666666666");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth6") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth7)
{
if( skb->mark == param_eth7 )
{
printk("\n salam, l'intetrface eth7777777777777");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth7") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth8)
{
if( skb->mark == param_eth8 )
{
printk("\n salam, l'intetrface eth8888888888888");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth8") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth9)
{
if( skb->mark == param_eth9 )
{
printk("\n salam, l'intetrface eth9999999999999");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth9") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth10)
{
if( skb->mark == param_eth10 )
{
printk("\n salam, l'intetrface eth10 10 10 10 10 10 10");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth10") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth11)
{
if( skb->mark == param_eth11 )
{
printk("\n salam, l'intetrface eth11 11 11 11 11 11 11");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth11") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth12)
{
if( skb->mark == param_eth12 )
{
printk("\n salam, l'intetrface eth12 12 12 12 12 12 12");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth12") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth13)
{
if( skb->mark == param_eth13 )
{
printk("\n salam, l'intetrface eth13 13 13 13 13 13 13");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth13") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth14)
{
if( skb->mark == param_eth14 )
{
printk("\n salam, l'intetrface eth14 14 14 14 14 14 14");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth14") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

if(eth15)
{
if( skb->mark == param_eth15 )
{
printk("\n salam, l'intetrface eth15 15 15 15 15 15 15");
bond_for_each_slave(bond, slave, i) {
if(strcmp(slave->dev->name, "eth15") == 0 ) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
goto out;
}
}
}
}

res = bond_xmit_my_roundrobin(skb, bond_dev1);

out:
if(res) {
dev_kfree_skb(skb);
}
read_unlock(&bond->lock);

return 0;
}

/***************************mpodficationnnnnnnnnnnn**********************************/


static int bond_xmit_activebackup(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
int res = 1;

read_lock(&bond->lock);
read_lock(&bond->curr_slave_lock);

if (!BOND_IS_OK(bond)) {
goto out;
}

if (!bond->curr_active_slave)
goto out;

res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);

out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
read_unlock(&bond->curr_slave_lock);
read_unlock(&bond->lock);
return 0;
}

/*
* In bond_xmit_xor() , we determine the output device by using a pre-
* determined xmit_hash_policy(), If the selected device is not enabled,
* find the next active slave.
*/
static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *start_at;
int slave_no;
int i;
int res = 1;

read_lock(&bond->lock);

if (!BOND_IS_OK(bond)) {
goto out;
}

slave_no = bond->xmit_hash_policy(skb, bond_dev, bond->slave_cnt);

bond_for_each_slave(bond, slave, i) {
slave_no--;
if (slave_no < 0) {
break;
}
}

start_at = slave;

bond_for_each_slave_from(bond, slave, i, start_at) {
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
(slave->state == BOND_STATE_ACTIVE)) {
res = bond_dev_queue_xmit(bond, skb, slave->dev);
break;
}
}

out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
read_unlock(&bond->lock);
return 0;
}

/*
* in broadcast mode, we send everything to all usable interfaces.
*/
static int bond_xmit_broadcast(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
struct slave *slave, *start_at;
struct net_device *tx_dev = NULL;
int i;
int res = 1;

read_lock(&bond->lock);

if (!BOND_IS_OK(bond)) {
goto out;
}

read_lock(&bond->curr_slave_lock);
start_at = bond->curr_active_slave;
read_unlock(&bond->curr_slave_lock);

if (!start_at) {
goto out;
}

bond_for_each_slave_from(bond, slave, i, start_at) {
if (IS_UP(slave->dev) &&
(slave->link == BOND_LINK_UP) &&
(slave->state == BOND_STATE_ACTIVE)) {
if (tx_dev) {
struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
if (!skb2) {
printk(KERN_ERR DRV_NAME
": %s: Error: bond_xmit_broadcast(): "
"skb_clone() failed\n",
bond_dev->name);
continue;
}

res = bond_dev_queue_xmit(bond, skb2, tx_dev);
if (res) {
dev_kfree_skb(skb2);
continue;
}
}
tx_dev = slave->dev;
}
}

if (tx_dev) {
res = bond_dev_queue_xmit(bond, skb, tx_dev);
}

out:
if (res) {
/* no suitable interface, frame not sent */
dev_kfree_skb(skb);
}
/* frame sent to all suitable interfaces */
read_unlock(&bond->lock);
return 0;
}

/*------------------------- Device initialization ---------------------------*/

static void bond_set_xmit_hash_policy(struct bonding *bond)
{
switch (bond->params.xmit_policy) {
case BOND_XMIT_POLICY_LAYER23:
bond->xmit_hash_policy = bond_xmit_hash_policy_l23;
break;
case BOND_XMIT_POLICY_LAYER34:
bond->xmit_hash_policy = bond_xmit_hash_policy_l34;
break;
case BOND_XMIT_POLICY_LAYER2:
default:
bond->xmit_hash_policy = bond_xmit_hash_policy_l2;
break;
}
}

static int bond_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
const struct bonding *bond = netdev_priv(dev);

switch (bond->params.mode) {
case BOND_MODE_ROUNDROBIN:
return bond_xmit_roundrobin(skb, dev);
case BOND_MODE_ACTIVEBACKUP:
return bond_xmit_activebackup(skb, dev);
case BOND_MODE_XOR:
return bond_xmit_xor(skb, dev);
case BOND_MODE_BROADCAST:
return bond_xmit_broadcast(skb, dev);
case BOND_MODE_8023AD:
return bond_3ad_xmit_xor(skb, dev);
case BOND_MODE_ALB:
case BOND_MODE_TLB:
return bond_alb_xmit(skb, dev);
case BOND_MODE_NOUVEAU: /**************************modificationnnnnnnnnn*************************/
return bond_xmit_nouveau(skb, dev); /**************************moeificationnnnnnnnnn*************************/
default:
/* Should never happen, mode already checked */
printk(KERN_ERR DRV_NAME ": %s: Error: Unknown bonding mode %d\n",
dev->name, bond->params.mode);
WARN_ON_ONCE(1);
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
}


/*
* set bond mode specific net device operations
*/
void bond_set_mode_ops(struct bonding *bond, int mode)
{
struct net_device *bond_dev = bond->dev;

switch (mode) {
case BOND_MODE_ROUNDROBIN:
break;
case BOND_MODE_ACTIVEBACKUP:
break;
case BOND_MODE_XOR:
bond_set_xmit_hash_policy(bond);
break;
case BOND_MODE_BROADCAST:
break;
case BOND_MODE_8023AD:
bond_set_master_3ad_flags(bond);
bond_set_xmit_hash_policy(bond);
break;
case BOND_MODE_ALB:
bond_set_master_alb_flags(bond);
/* FALLTHRU */
case BOND_MODE_TLB:
break;
case BOND_MODE_NOUVEAU: /**************************modificationnnnnnnnnn********************************/
break; /**************************modificationnnnnnnnnn********************************/
default:
/* Should never happen, mode already checked */
printk(KERN_ERR DRV_NAME
": %s: Error: Unknown bonding mode %d\n",
bond_dev->name,
mode);
break;
}
}

static void bond_ethtool_get_drvinfo(struct net_device *bond_dev,
struct ethtool_drvinfo *drvinfo)
{
strncpy(drvinfo->driver, DRV_NAME, 32);
strncpy(drvinfo->version, DRV_VERSION, 32);
snprintf(drvinfo->fw_version, 32, "%d", BOND_ABI_VERSION);
}

static const struct ethtool_ops bond_ethtool_ops = {
.get_drvinfo = bond_ethtool_get_drvinfo,
.get_link = ethtool_op_get_link,
.get_tx_csum = ethtool_op_get_tx_csum,
.get_sg = ethtool_op_get_sg,
.get_tso = ethtool_op_get_tso,
.get_ufo = ethtool_op_get_ufo,
.get_flags = ethtool_op_get_flags,
};

static const struct net_device_ops bond_netdev_ops = {
.ndo_open = bond_open,
.ndo_stop = bond_close,
.ndo_start_xmit = bond_start_xmit,
.ndo_get_stats = bond_get_stats,
.ndo_do_ioctl = bond_do_ioctl,
.ndo_set_multicast_list = bond_set_multicast_list,
.ndo_change_mtu = bond_change_mtu,
.ndo_set_mac_address = bond_set_mac_address,
.ndo_neigh_setup = bond_neigh_setup,
.ndo_vlan_rx_register = bond_vlan_rx_register,
.ndo_vlan_rx_add_vid = bond_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = bond_vlan_rx_kill_vid,
};


/*
* Does not allocate but creates a /proc entry.
* Allowed to fail.
*/
static int bond_init(struct net_device *bond_dev, struct bond_params *params)
{
struct bonding *bond = netdev_priv(bond_dev);

pr_debug("Begin bond_init for %s\n", bond_dev->name);

/* initialize rwlocks */
rwlock_init(&bond->lock);
rwlock_init(&bond->curr_slave_lock);

bond->params = *params; /* copy params struct */

bond->wq = create_singlethread_workqueue(bond_dev->name);
if (!bond->wq)
return -ENOMEM;

/* Initialize pointers */
bond->first_slave = NULL;
bond->curr_active_slave = NULL;
bond->current_arp_slave = NULL;
bond->primary_slave = NULL;
bond->dev = bond_dev;
bond->send_grat_arp = 0;
bond->send_unsol_na = 0;
bond->setup_by_slave = 0;
INIT_LIST_HEAD(&bond->vlan_list);

/* Initialize the device entry points */
bond_dev->netdev_ops = &bond_netdev_ops;
bond_dev->ethtool_ops = &bond_ethtool_ops;
bond_set_mode_ops(bond, bond->params.mode);

bond_dev->destructor = bond_destructor;

/* Initialize the device options */
bond_dev->tx_queue_len = 0;
bond_dev->flags |= IFF_MASTER|IFF_MULTICAST;
bond_dev->priv_flags |= IFF_BONDING;
if (bond->params.arp_interval)
bond_dev->priv_flags |= IFF_MASTER_ARPMON;

/* At first, we block adding VLANs. That's the only way to
* prevent problems that occur when adding VLANs over an
* empty bond. The block will be removed once non-challenged
* slaves are enslaved.
*/
bond_dev->features |= NETIF_F_VLAN_CHALLENGED;

/* don't acquire bond device's netif_tx_lock when
* transmitting */
bond_dev->features |= NETIF_F_LLTX;

/* By default, we declare the bond to be fully
* VLAN hardware accelerated capable. Special
* care is taken in the various xmit functions
* when there are slaves that are not hw accel
* capable
*/
bond_dev->features |= (NETIF_F_HW_VLAN_TX |
NETIF_F_HW_VLAN_RX |
NETIF_F_HW_VLAN_FILTER);

#ifdef CONFIG_PROC_FS
bond_create_proc_entry(bond);
#endif
list_add_tail(&bond->bond_list, &bond_dev_list);

return 0;
}

static void bond_work_cancel_all(struct bonding *bond)
{
write_lock_bh(&bond->lock);
bond->kill_timers = 1;
write_unlock_bh(&bond->lock);

if (bond->params.miimon && delayed_work_pending(&bond->mii_work))
cancel_delayed_work(&bond->mii_work);

if (bond->params.arp_interval && delayed_work_pending(&bond->arp_work))
cancel_delayed_work(&bond->arp_work);

if (bond->params.mode == BOND_MODE_ALB &&
delayed_work_pending(&bond->alb_work))
cancel_delayed_work(&bond->alb_work);

if (bond->params.mode == BOND_MODE_8023AD &&
delayed_work_pending(&bond->ad_work))
cancel_delayed_work(&bond->ad_work);
}

/* De-initialize device specific data.
* Caller must hold rtnl_lock.
*/
static void bond_deinit(struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);

list_del(&bond->bond_list);

bond_work_cancel_all(bond);

#ifdef CONFIG_PROC_FS
bond_remove_proc_entry(bond);
#endif
}

/* Unregister and free all bond devices.
* Caller must hold rtnl_lock.
*/
static void bond_free_all(void)
{
struct bonding *bond, *nxt;

list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
struct net_device *bond_dev = bond->dev;

bond_work_cancel_all(bond);
/* Release the bonded slaves */
bond_release_all(bond_dev);
bond_destroy(bond);
}

#ifdef CONFIG_PROC_FS
bond_destroy_proc_dir();
#endif
}

/*------------------------- Module initialization ---------------------------*/

/*
* Convert string input module parms. Accept either the
* number of the mode or its string name. A bit complicated because
* some mode names are substrings of other names, and calls from sysfs
* may have whitespace in the name (trailing newlines, for example).
*/
int bond_parse_parm(const char *buf, const struct bond_parm_tbl *tbl)
{
int mode = -1, i, rv;
char *p, modestr[BOND_MAX_MODENAME_LEN + 1] = { 0, };

for (p = (char *)buf; *p; p++)
if (!(isdigit(*p) || isspace(*p)))
break;

if (*p)
rv = sscanf(buf, "%20s", modestr);
else
rv = sscanf(buf, "%d", &mode);

if (!rv)
return -1;

for (i = 0; tbl.modename; i++) {
if (mode == tbl.mode)
return tbl.mode;
if (strcmp(modestr, tbl.modename) == 0)
return tbl.mode;
}

return -1;
}

static int bond_check_params(struct bond_params *params)
{
int arp_validate_value, fail_over_mac_value;

/*
* Convert string parameters.
*/
if (mode) {
bond_mode = bond_parse_parm(mode, bond_mode_tbl);
if (bond_mode == -1) {
printk(KERN_ERR DRV_NAME
": Error: Invalid bonding mode \"%s\"\n",
mode == NULL ? "NULL" : mode);
return -EINVAL;
}
}
/**************modificatiionnnnnnnnnnnn************/


if(bond_mode == BOND_MODE_NOUVEAU) {
if((!eth0)&&(!eth1))
printk("\n erreur, il faut féfinire une interface, eth0 ou eth1\n");
}


if(eth0) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth0 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth0, NULL, 0);
bond_ethx_tbl[j].modename = "eth0";
param_eth0 = simple_strtol(eth0, NULL, 0);
}


if(eth1) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth1 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));

}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth1, NULL, 0);
bond_ethx_tbl[j].modename = "eth1";
param_eth1 = simple_strtol(eth1, NULL, 0);
}


if(eth2) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth2 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth2, NULL, 0);
bond_ethx_tbl[j].modename = "eth2";
param_eth2 = simple_strtol(eth2, NULL, 0);
}

if(eth3) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth3 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth3, NULL, 0);
bond_ethx_tbl[j].modename = "eth3";
param_eth3 = simple_strtol(eth3, NULL, 0);
}

if(eth4) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth4 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth4, NULL, 0);
bond_ethx_tbl[j].modename = "eth4";
param_eth4 = simple_strtol(eth4, NULL, 0);
}

if(eth5) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth5 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth5, NULL, 0);
bond_ethx_tbl[j].modename = "eth5";
param_eth5 = simple_strtol(eth5, NULL, 0);
}

if(eth6) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth6 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth6, NULL, 0);
bond_ethx_tbl[j].modename = "eth6";
param_eth6 = simple_strtol(eth6, NULL, 0);
}

if(eth7) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth7 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth7, NULL, 0);
bond_ethx_tbl[j].modename = "eth7";
param_eth7 = simple_strtol(eth7, NULL, 0);
}

if(eth8) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth8 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth8, NULL, 0);
bond_ethx_tbl[j].modename = "eth8";
param_eth8 = simple_strtol(eth8, NULL, 0);
}

if(eth9) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth9 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth9, NULL, 0);
bond_ethx_tbl[j].modename = "eth9";
param_eth9 = simple_strtol(eth9, NULL, 0);
}

if(eth10) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth10 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth10, NULL, 0);
bond_ethx_tbl[j].modename = "eth10";
param_eth10 = simple_strtol(eth10, NULL, 0);
}

if(eth11) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth11 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth11, NULL, 0);
bond_ethx_tbl[j].modename = "eth11";
param_eth11 = simple_strtol(eth11, NULL, 0);
}

if(eth12) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth12 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth12, NULL, 0);
bond_ethx_tbl[j].modename = "eth12";
param_eth12 = simple_strtol(eth12, NULL, 0);
}

if(eth13) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth13 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth13, NULL, 0);
bond_ethx_tbl[j].modename = "eth13";
param_eth13 = simple_strtol(eth13, NULL, 0);
}

if(eth14) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth14 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth14, NULL, 0);
bond_ethx_tbl[j].modename = "eth14";
param_eth14 = simple_strtol(eth14, NULL, 0);
}
if(eth15) {
if( bond_mode != BOND_MODE_NOUVEAU) {
printk(KERN_INFO DRV_NAME
": eth15 param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
}
j = j+1;
bond_ethx_tbl[j].mode = simple_strtol(eth15, NULL, 0);
bond_ethx_tbl[j].modename = "eth15";
param_eth15 = simple_strtol(eth15, NULL, 0);
}

/*************modificationnnnnnnnnnn***************/

if (xmit_hash_policy) {
if ((bond_mode != BOND_MODE_8023AD)) {
printk(KERN_INFO DRV_NAME
": xor_mode param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
} else {
xmit_hashtype = bond_parse_parm(xmit_hash_policy,
xmit_hashtype_tbl);
if (xmit_hashtype == -1) {
printk(KERN_ERR DRV_NAME
": Error: Invalid xmit_hash_policy \"%s\"\n",
xmit_hash_policy == NULL ? "NULL" :
xmit_hash_policy);
return -EINVAL;
}
}
}

if (lacp_rate) {
if (bond_mode != BOND_MODE_8023AD) {
printk(KERN_INFO DRV_NAME
": lacp_rate param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
} else {
lacp_fast = bond_parse_parm(lacp_rate, bond_lacp_tbl);
if (lacp_fast == -1) {
printk(KERN_ERR DRV_NAME
": Error: Invalid lacp rate \"%s\"\n",
lacp_rate == NULL ? "NULL" : lacp_rate);
return -EINVAL;
}
}
}

if (ad_select) {
params->ad_select = bond_parse_parm(ad_select, ad_select_tbl);
if (params->ad_select == -1) {
printk(KERN_ERR DRV_NAME
": Error: Invalid ad_select \"%s\"\n",
ad_select == NULL ? "NULL" : ad_select);
return -EINVAL;
}

if (bond_mode != BOND_MODE_8023AD) {
printk(KERN_WARNING DRV_NAME
": ad_select param only affects 802.3ad mode\n");
}
} else {
params->ad_select = BOND_AD_STABLE;
}

if (max_bonds < 0 || max_bonds > INT_MAX) {
printk(KERN_WARNING DRV_NAME
": Warning: max_bonds (%d) not in range %d-%d, so it "
"was reset to BOND_DEFAULT_MAX_BONDS (%d)\n",
max_bonds, 0, INT_MAX, BOND_DEFAULT_MAX_BONDS);
max_bonds = BOND_DEFAULT_MAX_BONDS;
}

if (miimon < 0) {
printk(KERN_WARNING DRV_NAME
": Warning: miimon module parameter (%d), "
"not in range 0-%d, so it was reset to %d\n",
miimon, INT_MAX, BOND_LINK_MON_INTERV);
miimon = BOND_LINK_MON_INTERV;
}

if (updelay < 0) {
printk(KERN_WARNING DRV_NAME
": Warning: updelay module parameter (%d), "
"not in range 0-%d, so it was reset to 0\n",
updelay, INT_MAX);
updelay = 0;
}

if (downdelay < 0) {
printk(KERN_WARNING DRV_NAME
": Warning: downdelay module parameter (%d), "
"not in range 0-%d, so it was reset to 0\n",
downdelay, INT_MAX);
downdelay = 0;
}

if ((use_carrier != 0) && (use_carrier != 1)) {
printk(KERN_WARNING DRV_NAME
": Warning: use_carrier module parameter (%d), "
"not of valid value (0/1), so it was set to 1\n",
use_carrier);
use_carrier = 1;
}

if (num_grat_arp < 0 || num_grat_arp > 255) {
printk(KERN_WARNING DRV_NAME
": Warning: num_grat_arp (%d) not in range 0-255 so it "
"was reset to 1 \n", num_grat_arp);
num_grat_arp = 1;
}

if (num_unsol_na < 0 || num_unsol_na > 255) {
printk(KERN_WARNING DRV_NAME
": Warning: num_unsol_na (%d) not in range 0-255 so it "
"was reset to 1 \n", num_unsol_na);
num_unsol_na = 1;
}

/* reset values for 802.3ad */
if (bond_mode == BOND_MODE_8023AD) {
if (!miimon) {
printk(KERN_WARNING DRV_NAME
": Warning: miimon must be specified, "
"otherwise bonding will not detect link "
"failure, speed and duplex which are "
"essential for 802.3ad operation\n");
printk(KERN_WARNING "Forcing miimon to 100msec\n");
miimon = 100;
}
}

/* reset values for TLB/ALB */
if ((bond_mode == BOND_MODE_TLcool smiley ||
(bond_mode == BOND_MODE_ALcool smiley) {
if (!miimon) {
printk(KERN_WARNING DRV_NAME
": Warning: miimon must be specified, "
"otherwise bonding will not detect link "
"failure and link speed which are essential "
"for TLB/ALB load balancing\n");
printk(KERN_WARNING "Forcing miimon to 100msec\n");
miimon = 100;
}
}

if (bond_mode == BOND_MODE_ALcool smiley {
printk(KERN_NOTICE DRV_NAME
": In ALB mode you might experience client "
"disconnections upon reconnection of a link if the "
"bonding module updelay parameter (%d msec) is "
"incompatible with the forwarding delay time of the "
"switch\n",
updelay);
}

if (!miimon) {
if (updelay || downdelay) {
/* just warn the user the up/down delay will have
* no effect since miimon is zero...
*/
printk(KERN_WARNING DRV_NAME
": Warning: miimon module parameter not set "
"and updelay (%d) or downdelay (%d) module "
"parameter is set; updelay and downdelay have "
"no effect unless miimon is set\n",
updelay, downdelay);
}
} else {
/* don't allow arp monitoring */
if (arp_interval) {
printk(KERN_WARNING DRV_NAME
": Warning: miimon (%d) and arp_interval (%d) "
"can't be used simultaneously, disabling ARP "
"monitoring\n",
miimon, arp_interval);
arp_interval = 0;
}

if ((updelay % miimon) != 0) {
printk(KERN_WARNING DRV_NAME
": Warning: updelay (%d) is not a multiple "
"of miimon (%d), updelay rounded to %d ms\n",
updelay, miimon, (updelay / miimon) * miimon);
}

updelay /= miimon;

if ((downdelay % miimon) != 0) {
printk(KERN_WARNING DRV_NAME
": Warning: downdelay (%d) is not a multiple "
"of miimon (%d), downdelay rounded to %d ms\n",
downdelay, miimon,
(downdelay / miimon) * miimon);
}

downdelay /= miimon;
}

if (arp_interval < 0) {
printk(KERN_WARNING DRV_NAME
": Warning: arp_interval module parameter (%d) "
", not in range 0-%d, so it was reset to %d\n",
arp_interval, INT_MAX, BOND_LINK_ARP_INTERV);
arp_interval = BOND_LINK_ARP_INTERV;
}

for (arp_ip_count = 0;
(arp_ip_count < BOND_MAX_ARP_TARGETS) && arp_ip_target[arp_ip_count];
arp_ip_count++) {
/* not complete check, but should be good enough to
catch mistakes */
if (!isdigit(arp_ip_target[arp_ip_count][0])) {
printk(KERN_WARNING DRV_NAME
": Warning: bad arp_ip_target module parameter "
"(%s), ARP monitoring will not be performed\n",
arp_ip_target[arp_ip_count]);
arp_interval = 0;
} else {
__be32 ip = in_aton(arp_ip_target[arp_ip_count]);
arp_target[arp_ip_count] = ip;
}
}

if (arp_interval && !arp_ip_count) {
/* don't allow arping if no arp_ip_target given... */
printk(KERN_WARNING DRV_NAME
": Warning: arp_interval module parameter (%d) "
"specified without providing an arp_ip_target "
"parameter, arp_interval was reset to 0\n",
arp_interval);
arp_interval = 0;
}

if (arp_validate) {
if (bond_mode != BOND_MODE_ACTIVEBACKUP) {
printk(KERN_ERR DRV_NAME
": arp_validate only supported in active-backup mode\n");
return -EINVAL;
}
if (!arp_interval) {
printk(KERN_ERR DRV_NAME
": arp_validate requires arp_interval\n");
return -EINVAL;
}

arp_validate_value = bond_parse_parm(arp_validate,
arp_validate_tbl);
if (arp_validate_value == -1) {
printk(KERN_ERR DRV_NAME
": Error: invalid arp_validate \"%s\"\n",
arp_validate == NULL ? "NULL" : arp_validate);
return -EINVAL;
}
} else
arp_validate_value = 0;

if (miimon) {
printk(KERN_INFO DRV_NAME
": MII link monitoring set to %d ms\n",
miimon);
} else if (arp_interval) {
int i;

printk(KERN_INFO DRV_NAME
": ARP monitoring set to %d ms, validate %s, with %d target(s):",
arp_interval,
arp_validate_tbl[arp_validate_value].modename,
arp_ip_count);

for (i = 0; i < arp_ip_count; i++)
printk (" %s", arp_ip_target);

printk("\n");

} else if (max_bonds) {
/* miimon and arp_interval not set, we need one so things
* work as expected, see bonding.txt for details
*/
printk(KERN_WARNING DRV_NAME
": Warning: either miimon or arp_interval and "
"arp_ip_target module parameters must be specified, "
"otherwise bonding will not detect link failures! see "
"bonding.txt for details.\n");
}

if (primary && !USES_PRIMARY(bond_mode)) {
/* currently, using a primary only makes sense
* in active backup, TLB or ALB modes
*/
printk(KERN_WARNING DRV_NAME
": Warning: %s primary device specified but has no "
"effect in %s mode\n",
primary, bond_mode_name(bond_mode));
primary = NULL;
}

if (fail_over_mac) {
fail_over_mac_value = bond_parse_parm(fail_over_mac,
fail_over_mac_tbl);
if (fail_over_mac_value == -1) {
printk(KERN_ERR DRV_NAME
": Error: invalid fail_over_mac \"%s\"\n",
arp_validate == NULL ? "NULL" : arp_validate);
return -EINVAL;
}

if (bond_mode != BOND_MODE_ACTIVEBACKUP)
printk(KERN_WARNING DRV_NAME
": Warning: fail_over_mac only affects "
"active-backup mode.\n");
} else {
fail_over_mac_value = BOND_FOM_NONE;
}

/* fill params struct with the proper values */
params->mode = bond_mode;
params->xmit_policy = xmit_hashtype;
params->miimon = miimon;
params->num_grat_arp = num_grat_arp;
params->num_unsol_na = num_unsol_na;
params->arp_interval = arp_interval;
params->arp_validate = arp_validate_value;
params->updelay = updelay;
params->downdelay = downdelay;
params->use_carrier = use_carrier;
params->lacp_fast = lacp_fast;
params->primary[0] = 0;
params->fail_over_mac = fail_over_mac_value;

if (primary) {
strncpy(params->primary, primary, IFNAMSIZ);
params->primary[IFNAMSIZ - 1] = 0;
}

memcpy(params->arp_targets, arp_target, sizeof(arp_target));

return 0;
}

static struct lock_class_key bonding_netdev_xmit_lock_key;
static struct lock_class_key bonding_netdev_addr_lock_key;

static void bond_set_lockdep_class_one(struct net_device *dev,
struct netdev_queue *txq,
void *_unused)
{
lockdep_set_class(&txq->_xmit_lock,
&bonding_netdev_xmit_lock_key);
}

static void bond_set_lockdep_class(struct net_device *dev)
{
lockdep_set_class(&dev->addr_list_lock,
&bonding_netdev_addr_lock_key);
netdev_for_each_tx_queue(dev, bond_set_lockdep_class_one, NULL);
}

/* Create a new bond based on the specified name and bonding parameters.
* If name is NULL, obtain a suitable "bond%d" name for us.
* Caller must NOT hold rtnl_lock; we need to release it here before we
* set up our sysfs entries.
*/
int bond_create(char *name, struct bond_params *params)
{
struct net_device *bond_dev;
struct bonding *bond;
int res;

rtnl_lock();
down_write(&bonding_rwsem);

/* Check to see if the bond already exists. */
if (name) {
list_for_each_entry(bond, &bond_dev_list, bond_list)
if (strnicmp(bond->dev->name, name, IFNAMSIZ) == 0) {
printk(KERN_ERR DRV_NAME
": cannot add bond %s; it already exists\n",
name);
res = -EPERM;
goto out_rtnl;
}
}

bond_dev = alloc_netdev(sizeof(struct bonding), name ? name : "",
ether_setup);
if (!bond_dev) {
printk(KERN_ERR DRV_NAME
": %s: eek! can't alloc netdev!\n",
name);
res = -ENOMEM;
goto out_rtnl;
}

if (!name) {
res = dev_alloc_name(bond_dev, "bond%d");
if (res < 0)
goto out_netdev;
}

/* bond_init() must be called after dev_alloc_name() (for the
* /proc files), but before register_netdevice(), because we
* need to set function pointers.
*/

res = bond_init(bond_dev, params);
if (res < 0) {
goto out_netdev;
}

res = register_netdevice(bond_dev);
if (res < 0) {
goto out_bond;
}

bond_set_lockdep_class(bond_dev);

netif_carrier_off(bond_dev);

up_write(&bonding_rwsem);
rtnl_unlock(); /* allows sysfs registration of net device */
res = bond_create_sysfs_entry(netdev_priv(bond_dev));
if (res < 0) {
rtnl_lock();
down_write(&bonding_rwsem);
bond_deinit(bond_dev);
unregister_netdevice(bond_dev);
goto out_rtnl;
}

return 0;

out_bond:
bond_deinit(bond_dev);
out_netdev:
free_netdev(bond_dev);
out_rtnl:
up_write(&bonding_rwsem);
rtnl_unlock();
return res;
}

static int __init bonding_init(void)
{
int i;
int res;
struct bonding *bond;

printk(KERN_INFO "%s", version);

res = bond_check_params(&bonding_defaults);
if (res) {
goto out;
}

#ifdef CONFIG_PROC_FS
bond_create_proc_dir();
#endif

init_rwsem(&bonding_rwsem);

for (i = 0; i < max_bonds; i++) {
res = bond_create(NULL, &bonding_defaults);
if (res)
goto err;
}

res = bond_create_sysfs();
if (res)
goto err;

register_netdevice_notifier(&bond_netdev_notifier);
register_inetaddr_notifier(&bond_inetaddr_notifier);
bond_register_ipv6_notifier();

goto out;
err:
list_for_each_entry(bond, &bond_dev_list, bond_list) {
bond_work_cancel_all(bond);
destroy_workqueue(bond->wq);
}

bond_destroy_sysfs();

rtnl_lock();
bond_free_all();
rtnl_unlock();
out:
return res;

}

static void __exit bonding_exit(void)
{
unregister_netdevice_notifier(&bond_netdev_notifier);
unregister_inetaddr_notifier(&bond_inetaddr_notifier);
bond_unregister_ipv6_notifier();

bond_destroy_sysfs();

rtnl_lock();
bond_free_all();
rtnl_unlock();
}

module_init(bonding_init);
module_exit(bonding_exit);
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
MODULE_DESCRIPTION(DRV_DESCRIPTION ", v" DRV_VERSION);
MODULE_AUTHOR("Thomas Davis, tadavis@lbl.gov and many others");
MODULE_SUPPORTED_DEVICE("most ethernet devices");

/*
* Local variables:
* c-indent-level: 8
* c-basic-offset: 8
* tab-width: 8
* End:
*/

J'espère que ça va aidé des personnes dans le future.

Poste le Tuesday 21 July 2009 23:55:05
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
programmation kernel
Aide sur les distributions Debian, Ubuntu et leurs dérivées : Mepis, Mint, Knoppix, Kubuntu, Lubuntu, Xandros

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons