ead: use the new pcap features and the raw socket optimization to eliminate most of the cpu utilization overhead caused by the use of pcap live capturing
SVN-Revision: 15400
This commit is contained in:
parent
4898039703
commit
73883e9aef
2 changed files with 61 additions and 4 deletions
|
@ -11,8 +11,10 @@ PKG_NAME:=ead
|
|||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DEPENDS:=libpcap
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/ead
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/kernel.mk
|
||||
|
||||
define Package/ead
|
||||
SECTION:=net
|
||||
|
@ -29,6 +31,7 @@ endef
|
|||
CONFIGURE_PATH = tinysrp
|
||||
|
||||
TARGET_CFLAGS += \
|
||||
-I$(LINUX_DIR)/include \
|
||||
-I$(PKG_BUILD_DIR) \
|
||||
-I$(PKG_BUILD_DIR)/tinysrp \
|
||||
$(TARGET_CPPFLAGS)
|
||||
|
|
|
@ -42,6 +42,10 @@
|
|||
#include "libbridge_init.c"
|
||||
#endif
|
||||
|
||||
#ifdef linux
|
||||
#include <linux/if_packet.h>
|
||||
#endif
|
||||
|
||||
#define PASSWD_FILE "/etc/passwd"
|
||||
|
||||
#ifndef DEFAULT_IFNAME
|
||||
|
@ -110,6 +114,51 @@ static struct t_server *ts = NULL;
|
|||
static struct t_num A, *B = NULL;
|
||||
unsigned char *skey;
|
||||
|
||||
static void
|
||||
set_recv_type(pcap_t *p, bool rx)
|
||||
{
|
||||
#ifdef PACKET_RECV_TYPE
|
||||
struct sockaddr_ll sll;
|
||||
struct ifreq ifr;
|
||||
int ifindex, mask;
|
||||
int fd, ret;
|
||||
|
||||
fd = pcap_get_selectable_fd(p);
|
||||
if (fd < 0)
|
||||
return;
|
||||
|
||||
if (rx)
|
||||
mask = 1 << PACKET_BROADCAST;
|
||||
else
|
||||
mask = 0;
|
||||
|
||||
ret = setsockopt(fd, SOL_PACKET, PACKET_RECV_TYPE, &mask, sizeof(mask));
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static pcap_t *
|
||||
ead_open_pcap(const char *ifname, char *errbuf, bool rx)
|
||||
{
|
||||
pcap_t *p;
|
||||
|
||||
p = pcap_create(ifname, errbuf);
|
||||
if (p == NULL)
|
||||
goto out;
|
||||
|
||||
pcap_set_snaplen(p, PCAP_MRU);
|
||||
pcap_set_promisc(p, rx);
|
||||
pcap_set_timeout(p, PCAP_TIMEOUT);
|
||||
#ifdef HAS_PROTO_EXTENSION
|
||||
pcap_set_protocol(p, (rx ? htons(ETH_P_IP) : 0));
|
||||
#endif
|
||||
pcap_set_buffer_size(p, (rx ? 10 : 1) * PCAP_MRU);
|
||||
pcap_activate(p);
|
||||
set_recv_type(p, rx);
|
||||
out:
|
||||
return p;
|
||||
}
|
||||
|
||||
static void
|
||||
get_random_bytes(void *ptr, int len)
|
||||
{
|
||||
|
@ -647,14 +696,18 @@ ead_pcap_reopen(bool first)
|
|||
|
||||
pcap_fp_rx = NULL;
|
||||
do {
|
||||
pcap_fp = pcap_open_live(instance->ifname, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
|
||||
#ifdef linux
|
||||
if (instance->bridge[0])
|
||||
pcap_fp_rx = pcap_open_live(instance->bridge, PCAP_MRU, 1, PCAP_TIMEOUT, errbuf);
|
||||
if (instance->bridge[0]) {
|
||||
pcap_fp_rx = ead_open_pcap(instance->bridge, errbuf, 1);
|
||||
pcap_fp = ead_open_pcap(instance->ifname, errbuf, 0);
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
pcap_fp = ead_open_pcap(instance->ifname, errbuf, 1);
|
||||
}
|
||||
|
||||
if (!pcap_fp_rx)
|
||||
pcap_fp_rx = pcap_fp;
|
||||
pcap_setfilter(pcap_fp_rx, &pktfilter);
|
||||
if (first && !pcap_fp) {
|
||||
DEBUG(1, "WARNING: unable to open interface '%s'\n", instance->ifname);
|
||||
first = false;
|
||||
|
@ -662,6 +715,7 @@ ead_pcap_reopen(bool first)
|
|||
if (!pcap_fp)
|
||||
sleep(1);
|
||||
} while (!pcap_fp);
|
||||
pcap_setfilter(pcap_fp_rx, &pktfilter);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue