2013-02-27 19 views
5

Tôi có một câu hỏi liên quan đến cách gắn trình điều khiển có các gói RX từ các giao diện nô lệ. Tôi thấy rằng sử dụng liên kết dev_add_pack() để thiết lập các trình xử lý cho các gói LACPDU và ARP, nhưng tôi không tìm thấy các trình xử lý khác (đối với các loại gói khác).Trình điều khiển liên kết lấy các gói RX từ các giao diện enslave như thế nào

Bạn có thể giúp tôi giải quyết câu hỏi này không?

+1

+1, tôi ước tôi có thể giúp bạn ở đó. –

+0

OK, cảm ơn bạn, có vẻ như tôi đã tìm thấy câu trả lời, tôi nghĩ rằng tôi sẽ thêm nó ở đây, nhưng sau đó là –

Trả lời

2

trình điều khiển Bonding đăng ký xử lý Rx của riêng mình, khi một giao diện nô lệ là nô lệ cho một bậc thầy trái phiếu, trong bond_enslave(), bạn có thể thấy:

res = netdev_rx_handler_register(slave_dev, bond_handle_frame, 
           new_slave); 

Vì vậy, trong bond_handle_frame(), nó sẽ chiếm quyền điều khiển các gói tin đã nhận bởi giao diện nô lệ, để chủ nhân liên kết sẽ nhận các gói thay thế:

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

Cảm ơn bạn, có vẻ như tôi đã được kiểm tra phiên bản liên kết quá cũ, sau khi cập nhật từ kernel.org tôi tìm thấy mã mà bạn đã viết ở trên –

1

Tôi đã kiểm tra mã liên kết và thấy rằng trình điều khiển không kiểm tra gói RX đến mà không có một số loại (LACPDU, ARP) trong trường hợp, khi trình điều khiển hoạt động trong các chế độ này. Trình điều khiển thiết lập trình điều khiển cho các gói này có sử dụng hàm dev_add_pack().

Để đặt móc toàn cầu trong thực tế, bạn có thể sử dụng nf_register_hook(), cung cấp giao diện để thiết lập quy trình lọc mạng riêng cho các gói bị chặn. Dường như nf_register_hook() mạnh hơn dev_add_pack(), nhưng tôi nghĩ rằng cần phải cẩn thận hơn khi làm việc nf_register_hook(), bởi vì nó có thể thả rất nhiều gói trong trường hợp điều kiện sai trong móc.

Các vấn đề liên quan