From: Felix Fietkau Date: Sat, 25 Apr 2009 03:30:20 +0000 (+0000) Subject: ead: use the new pcap features and the raw socket optimization to eliminate most... X-Git-Url: http://git.openwrt.org/?p=openwrt%2Fstaging%2Fflorian.git;a=commitdiff_plain;h=73883e9aef6406d909d2e8c2bad997a74485609e 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 --- diff --git a/package/ead/Makefile b/package/ead/Makefile index 0ecff2a8ed..958577ff90 100644 --- a/package/ead/Makefile +++ b/package/ead/Makefile @@ -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) diff --git a/package/ead/src/ead.c b/package/ead/src/ead.c index 9ce6f56911..36235207bc 100644 --- a/package/ead/src/ead.c +++ b/package/ead/src/ead.c @@ -42,6 +42,10 @@ #include "libbridge_init.c" #endif +#ifdef linux +#include +#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); }