最近、高速 (500Mbitps 以上) でパケットを転送するプロジェクトに取り組んでいます。2つの方法を試しましたが、うまくいきません。ホストは vm、ubuntu-11.10 32 ビット、NIC は r8169、1000Mb です。
サイズが受信したパケットのサイズに依存するバフ付きの生の靴下を使用しました(1500以下)。sendto 関数を loop(while(1)) に入れ、できるだけ早く送信できることを確認します。しかし、送信速度は r8169 が実行できる速度よりもはるかに遅く、約 100 ~ 200Mbitps です。ソケットは高速送信ができないと思いますか? しかし、なぜIperfやuses socketなどの方がパフォーマンスが向上するのでしょうか? または送信を高速化するためにできることはありますか?
カーネルで dev_queue_xmit() を使用しました。schedule() を使用して kthread の loop(while(1)) に関数を入れました。しかし、送信速度は 300Mbitps 以下でした。call dev_queue_xmit はおそらく良い考えではないことはわかっていますが、なぜ速度が遅いのかまだわかりませんか?
助けてください..
または、パケットを高速で転送するための古典的なソリューションを誰かが提供してくれますか? 私のソケットは簡単です:
int sockfd = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_IP)/*IPPROTO_RAW*/);
struct ifreq if_idx;
char ifName[IFNAMSIZ];
struct sockaddr_ll socket_address;
char buf[1400];
struct packet_mreq mr;
struct ether_header *eh;
int ret = 0;
struct ifreq if_mac;
strcpy(ifName, "eth1");//used for sending
memset(&if_idx, 0, sizeof(struct ifreq));
strncpy(if_idx.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFINDEX, &if_idx) < 0)
perror("SIOCGIFINDEX\n");
memset(&if_mac, 0, sizeof(struct ifreq));
strncpy(if_mac.ifr_name, ifName, IFNAMSIZ-1);
if (ioctl(sockfd, SIOCGIFHWADDR, &if_mac) < 0)
perror("SIOCGIFHWADDR\n");
socket_address.sll_ifindex = if_idx.ifr_ifindex;
/* Address length*/
socket_address.sll_halen = ETH_ALEN;
/* Destination MAC */
socket_address.sll_family = AF_PACKET;
socket_address.sll_protocol = htons(0xA000);
socket_address.sll_addr[0] = 0x00;
socket_address.sll_addr[1] = 0x24;
socket_address.sll_addr[2] = 0xe8;
socket_address.sll_addr[3] = 0x82;
socket_address.sll_addr[4] = 0xec;
socket_address.sll_addr[5] = 0x82;
printf("%d\n",bind(sockfd, (struct sockaddr *) &socket_address, sizeof(socket_address)));
memset (&mr, 0, sizeof(mr));
mr.mr_ifindex = if_idx.ifr_ifindex;
//mr.mr_type = PACKET_MR_PROMISC;
setsockopt(sockfd, SOL_PACKET, PACKET_ADD_MEMBERSHIP, &mr,sizeof(mr));
eh = (struct ether_header *)buf;
eh->ether_shost[0] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[0];
eh->ether_shost[1] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[1];
eh->ether_shost[2] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[2];
eh->ether_shost[3] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[3];
eh->ether_shost[4] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[4];
eh->ether_shost[5] = ((uint8_t *)&if_mac.ifr_hwaddr.sa_data)[5];
eh->ether_dhost[0] = 0x00;
eh->ether_dhost[1] = 0x24;
eh->ether_dhost[2] = 0xe8;
eh->ether_dhost[3] = 0x82;
eh->ether_dhost[4] = 0xec;
eh->ether_dhost[5] = 0x82;
eh->ether_type = htons(0xA000);
while(1)
ret = write(sockfd,buf,1000);
printf("%d\n",ret);
return 0;