绑定和分配mmap内核空间(bind_ring)--(七)

本文介绍了PF_RING中套接字绑定的过程,包括bind函数调用的内部实现,以及packet_ring_bind函数的具体操作,如设备查找、旧绑定移除、新绑定添加等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

用户态在创建了套接字后,接下来就调用bind函数,绑定套接字,而PF_RING实际做的就是为RING分配相应的空间。也就是说,一个套接字,都有一个与之对应的RING。在前面我们已经提到  sock->ops = &ring_ops;这样当应用空间调用bind函数中,内核调用ring_bind函数;即当系统调用bind触发时,内核ring_bind函数就触发了。下面讲解ring_bind函数;

/* Bind to a device */

static int ring_bind(struct socket*sock, struct sockaddr *sa, int addr_len)

{

 struct sock *sk = sock->sk;

 if(enable_debug)

   printk("[PF_RING] ring_bind() called\n");

  /*

   *     Check legality

  */

 if(addr_len != sizeof(struct sockaddr))

   return -EINVAL;

 if(sa->sa_family != PF_RING)

   return -EINVAL;

 if(sa->sa_data == NULL)

   return -EINVAL;

  /* Safety check: add trailing zero if missing*/

 sa->sa_data[sizeof(sa->sa_data) - 1] = '\0';

  if(enable_debug)

   printk("[PF_RING] searching device %s\n", sa->sa_data);

#if 0

 if(strcmp(sa->sa_data, "any") == 0)

   dev = &any_dev;

 else {

   if((dev = __dev_get_by_name(

#if(LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,24))

                            &init_net,

#endif

                            sa->sa_data))== NULL) {

      if(enable_debug)

       printk("[PF_RING]search failed\n");

      return(-EINVAL);

   }

 }

#endif

 return(packet_ring_bind(sk,sa->sa_data));

}

 

ring_bind 函数前面都是一系列的判断,主要起作用的还是packet_ring_bind函数,函数定义如下:

static int packet_ring_bind(structsock *sk, char *dev_name)

{

 struct pf_ring_socket *pfr = ring_sk(sk);

 struct list_head *ptr, *tmp_ptr;

 ring_device_element *dev = NULL;

 if(dev_name == NULL)

   return(-EINVAL);

 list_for_each_safe(ptr, tmp_ptr, &ring_aware_device_list) {

   ring_device_element *dev_ptr = list_entry(ptr, ring_device_element,device_list);

   if(strcmp(dev_ptr->dev->name, dev_name) == 0) {

      dev = dev_ptr;

      break;

   }

 }

 

 if((dev == NULL) || (dev->dev->type != ARPHRD_ETHER))

   return(-EINVAL);

 if(enable_debug)

   printk("[PF_RING] packet_ring_bind(%s, bucket_len=%d)called\n",

          dev->dev->name, pfr->bucket_len);

 

  /* Remove old binding (by default binding tonone)

     BEFORE binding to a new device

  */

 ring_proc_remove(pfr);

 

  /*

IMPORTANT

Leave this statementhere as last one. In fact when

    the ring_netdev != &none_device_elementthe socket is ready to be used.

  */

 pfr->ring_netdev = dev;

 

  /* Timeto rebind to a new device */

 ring_proc_add(pfr);

  /*As the 'struct net_device' does not containthe number

    of RX queues, we can guess that its numberis the same as the number

    of TX queues. After the first packet hasbeen received by the adapter

    the num of RX queues is updated with thereal value

  */

#if(LINUX_VERSION_CODE >=KERNEL_VERSION(2,6,31))

 pfr->num_rx_channels =pfr->ring_netdev->dev->real_num_tx_queues;

#else

 pfr->num_rx_channels = 1;

#endif

 if(dev == &any_device_element)

   num_any_rings++;

 else {

   if(dev->dev->ifindex < MAX_NUM_IFIDX)

     num_rings_per_device[dev->dev->ifindex]++;

   else

      printk("[PF_RING] INTERNAL ERROR:ifindex %d for %s is > than MAX_NUM_IFIDX\n",

            dev->dev->ifindex, dev->dev->name);

 }

 return(0);

}

 

这个函数的主要作用是创建一个环状缓冲区的socket,然后对socket进行绑定。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值