2013-02-27 5 views
5

Ich habe eine Frage, wie Treiber zum Binden nimmt RX-Pakete von versklavten Schnittstellen. Ich fand, dass das Verbinden dev_add_pack() verwendet, um Handler für LACPDU- und ARP-Pakete zu setzen, aber ich habe keine anderen Handler gefunden (für andere Pakettypen).Wie Bindungstreiber nimmt RX-Pakete von versklaven Schnittstellen

Könnten Sie mir bitte helfen, diese Frage zu lösen?

+1

+1, ich wünschte, ich könnte Ihnen helfen. –

+0

OK, danke, scheint, dass ich Antwort gefunden wird, ich glaube, ich es hier hinzufügen würde, aber wenig später –

Antwort

2

Bonding Fahrer seinen eigenen Rx-Handler registriert, wenn eine Slave-Schnittstelle auf eine Bindung Master versklavt wird, in bond_enslave() können Sie sehen:

res = netdev_rx_handler_register(slave_dev, bond_handle_frame, 
           new_slave); 

So in bond_handle_frame(), wird es die Pakete kapern empfangen durch die Slave-Schnittstelle, so dass der Bond-Master stattdessen die Pakete erhalten:

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

Danke, scheint, dass ich zu alt Bindungs ​​Version geprüft, nach Updates von kernel.org gefunden I-Code, über die Sie schrieb oben –

1

Ich überprüft Code der Bindung und festgestellt, dass der Treiber eingehende RX-Pakete ohne einige der Typen (LACPDU, ARP) in Fällen nicht untersucht, wenn Treiber in diesen Modi arbeitet. Treiber setzen Handler für diese Pakete mit der Funktion dev_add_pack().

Für set global Haken in practic können Sie nf_register_hook() verwenden, die für das Setup Intercept-Pakete für Prozedur eigene Netzfilter-Schnittstelle zur Verfügung stellen. Es scheint, dass nf_register_hook() ist mächtiger als dev_add_pack(), aber ich denke, dass mehr Pflege benötigen, wenn nf_register_hook Arbeit(), weil es eine Menge von Paketen bei falscher Bedingungen in Haken fallen kann.

Verwandte Themen