2013-02-27 3 views
5

Ho una domanda su come collegare il driver ai pacchetti RX dalle interfacce slave. Ho trovato che bonding usa dev_add_pack() per impostare i gestori per i pacchetti LACPDU e ARP, ma non ho trovato altri gestori (per altri tipi di pacchetti).Come il driver di bonding accetta pacchetti RX dalle interfacce slave

Potresti per favore aiutarmi a risolvere questa domanda?

+1

+1, vorrei poterti aiutare. –

+0

OK, grazie, sembra che ho trovato la risposta, penso che lo aggiungerò qui, ma poco dopo –

risposta

2

driver Bonding registra il proprio gestore Rx, quando un'interfaccia slave è asservito ad un master legame, in bond_enslave() è possibile vedere:

res = netdev_rx_handler_register(slave_dev, bond_handle_frame, 
           new_slave); 

Quindi, in bond_handle_frame(), sarà dirottare i pacchetti ricevuti tramite l'interfaccia slave, in modo che il master bond riceva invece i pacchetti:

static rx_handler_result_t bond_handle_frame(struct sk_buff **pskb) 
{ 
     struct sk_buff *skb = *pskb; 
     struct slave *slave; 
     struct bonding *bond; 
     int (*recv_probe)(const struct sk_buff *, struct bonding *, 
          struct slave *); 
     int ret = RX_HANDLER_ANOTHER; 

     skb = skb_share_check(skb, GFP_ATOMIC); 
     if (unlikely(!skb)) 
       return RX_HANDLER_CONSUMED; 

     *pskb = skb; 

     slave = bond_slave_get_rcu(skb->dev); 
     bond = slave->bond; 

     if (bond->params.arp_interval) 
       slave->dev->last_rx = jiffies; 

     recv_probe = ACCESS_ONCE(bond->recv_probe); 
     if (recv_probe) { 
       ret = recv_probe(skb, bond, slave); 
       if (ret == RX_HANDLER_CONSUMED) { 
         consume_skb(skb); 
         return ret; 
       } 
     } 

     if (bond_should_deliver_exact_match(skb, slave, bond)) { 
       return RX_HANDLER_EXACT; 
     } 

     skb->dev = bond->dev; 

     if (bond->params.mode == BOND_MODE_ALB && 
      bond->dev->priv_flags & IFF_BRIDGE_PORT && 
      skb->pkt_type == PACKET_HOST) { 

       if (unlikely(skb_cow_head(skb, 
              skb->data - skb_mac_header(skb)))) { 
         kfree_skb(skb); 
         return RX_HANDLER_CONSUMED; 
       } 
       memcpy(eth_hdr(skb)->h_dest, bond->dev->dev_addr, ETH_ALEN); 
     } 

     return ret; 
} 
+0

Grazie, sembra che sia stata controllata la vecchia versione di bonding, dopo gli aggiornamenti di kernel.org ho trovato il codice su cui ha scritto sopra –

1

Ho controllato il codice di collegamento e ho rilevato che il driver non ispezionava i pacchetti RX in arrivo senza alcuni tipi (LACPDU, ARP) nei casi, quando il driver funziona in queste modalità. Driver set manager per questi pacchetti con l'uso della funzione dev_add_pack().

Per impostare il hook globale in pratica è possibile utilizzare nf_register_hook(), che fornisce un'interfaccia per l'impostazione della propria procedura di filtro di rete per i pacchetti di intercettazione. Sembra che nf_register_hook() sia più potente di dev_add_pack(), ma penso che sia necessario prestare maggiore attenzione quando si lavora nf_register_hook(), perché può rilasciare molti pacchetti in caso di condizioni errate in hook.

Problemi correlati