Chinaunix首页 | 论坛 | 博客
  • 博客访问: 305619
  • 博文数量: 71
  • 博客积分: 1450
  • 博客等级: 上尉
  • 技术积分: 715
  • 用 户 组: 普通用户
  • 注册时间: 2007-03-11 16:56
文章分类

全部博文(71)

文章存档

2010年(2)

2009年(12)

2008年(19)

2007年(38)

分类: LINUX

2008-08-14 12:36:27

ifconfig promisc内核处理流程:

ioctl(skfd, SIOCSIFFLAGS, &ifr)
...
int dev_ioctl(unsigned int cmd, void __user *arg) /*net/core/dev.c*/
    |
     ——>dev_ifsioc(struct ifreq *ifr, unsigned int cmd)
        |
         ——>int dev_change_flags(struct net_device *dev, unsigned flags)
                |
                 ——>void dev_set_promiscuity(struct net_device *dev, int inc)
                        |
                         ——>void dev_mc_upload(struct net_device *dev) /*net/core/dev_mcast.c*/
                            |
                             ——>dev->set_multicast_list(dev)
                                    |
                                    |
                               <——
...
/*驱动程序e1000_main.c*/
static void e1000_set_multi(struct net_device *netdev)
{
    struct e1000_adapter *adapter = netdev_priv(netdev);
    struct e1000_hw *hw = &adapter->hw;
    struct e1000_mac_info *mac = &hw->mac;
    struct dev_mc_list *mc_ptr;
    u8  *mta_list;
    u32 rctl;
    int i;

    /* Check for Promiscuous and All Multicast modes */

    rctl = E1000_READ_REG(hw, E1000_RCTL);

    if (netdev->flags & IFF_PROMISC) {
        rctl |= (E1000_RCTL_UPE | E1000_RCTL_MPE);
    } else if (netdev->flags & IFF_ALLMULTI) {
        rctl |= E1000_RCTL_MPE;
        rctl &= ~E1000_RCTL_UPE;
    } else {
        rctl &= ~(E1000_RCTL_UPE | E1000_RCTL_MPE);
    }

    E1000_WRITE_REG(hw, E1000_RCTL, rctl); /*写网卡寄存器*/

    /* 82542 2.0 needs to be in reset to write receive address registers */

    if (hw->mac.type == e1000_82542)
        e1000_enter_82542_rst(adapter);

    mta_list = kmalloc(netdev->mc_count * 6, GFP_ATOMIC);
    if (!mta_list)
        return;

    /* The shared function expects a packed array of only addresses. */
    mc_ptr = netdev->mc_list;

    for (i = 0; i < netdev->mc_count; i++) {
        if (!mc_ptr)
            break;
        memcpy(mta_list + (i*ETH_ALEN), mc_ptr->dmi_addr, ETH_ALEN);
        mc_ptr = mc_ptr->next;
    }

    e1000_update_mc_addr_list(hw, mta_list, i, 1, mac->rar_entry_count);

    kfree(mta_list);

    if (hw->mac.type == e1000_82542)
        e1000_leave_82542_rst(adapter);
}

阅读(2554) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~