aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFelix Fietkau <nbd@openwrt.org>2006-03-18 17:27:20 +0000
committerFelix Fietkau <nbd@openwrt.org>2006-03-18 17:27:20 +0000
commit5359dd8c8a0ad7c6c3ea7f0211b26b378263965f (patch)
tree52813f9ebd13e23690eceb048dcb8cfb54863a17
parenta10c122fe2cdd175541eb14cebe58d599b5c7dce (diff)
downloadmaster-187ad058-5359dd8c8a0ad7c6c3ea7f0211b26b378263965f.tar.gz
master-187ad058-5359dd8c8a0ad7c6c3ea7f0211b26b378263965f.tar.bz2
master-187ad058-5359dd8c8a0ad7c6c3ea7f0211b26b378263965f.zip
precompile ppp active filter (reduces libpcap overhead to only a few k), enable by default to support proper demand dialling, fixes #307
git-svn-id: svn://svn.openwrt.org/openwrt/trunk/openwrt@3401 3c298f89-4303-0410-b956-a3cf2f4a3e73
-rw-r--r--package/ppp/Config.in5
-rw-r--r--package/ppp/Makefile8
-rw-r--r--package/ppp/files/etc/ppp/filter23
-rw-r--r--package/ppp/files/ifup.pppoa1
-rw-r--r--package/ppp/files/ifup.pppoe1
-rw-r--r--package/ppp/patches/310-precompiled_filter.patch231
-rw-r--r--package/ppp/utils/pfc.c51
-rw-r--r--package/pptp/files/ifup.pptp1
8 files changed, 316 insertions, 5 deletions
diff --git a/package/ppp/Config.in b/package/ppp/Config.in
index 0dda3cc83f..21139adf77 100644
--- a/package/ppp/Config.in
+++ b/package/ppp/Config.in
@@ -8,10 +8,9 @@ config BR2_PACKAGE_PPP
select BR2_PACKAGE_KMOD_PPP
config BR2_PACKAGE_PPP_WITH_FILTER
- prompt "Enable filter support"
+ prompt "Enable filter support"
bool
- default n
- depends BR2_PACKAGE_LIBPCAP
+ default y
config BR2_PACKAGE_PPP_MOD_PPPOA
prompt "ppp-mod-pppoa................... PPPoA (PPP over ATM) plugin"
diff --git a/package/ppp/Makefile b/package/ppp/Makefile
index d98d7e5cb7..e63fa4cf50 100644
--- a/package/ppp/Makefile
+++ b/package/ppp/Makefile
@@ -41,8 +41,7 @@ $(eval $(call PKG_mod_template,PPP_MOD_RADIUS,radius))
PKG_DEPEND:="kmod-ppp"
ifeq ($(BR2_PACKAGE_PPP_WITH_FILTER),y)
-ENABLE_FILTER:="FILTER=1"
-PKG_DEPEND += ", libpcap"
+ENABLE_FILTER:="PRECOMPILED_FILTER=1"
endif
$(PKG_BUILD_DIR)/.configured:
@@ -85,11 +84,16 @@ $(PKG_BUILD_DIR)/.built:
all install
touch $@
+ifeq ($(BR2_PACKAGE_PPP_WITH_FILTER),y)
+INSTALL_FILTER=install -m0644 ./files/etc/ppp/filter $(IDIR_PPP)/etc/ppp/
+endif
+
$(IPKG_PPP):
install -d -m0755 $(IDIR_PPP)/etc/ppp
ln -sf /tmp/resolv.conf $(IDIR_PPP)/etc/ppp/resolv.conf
install -m0600 ./files/etc/ppp/chap-secrets $(IDIR_PPP)/etc/ppp/
install -m0644 ./files/etc/ppp/options $(IDIR_PPP)/etc/ppp/
+ $(INSTALL_FILTER)
install -m0755 ./files/etc/ppp/ip-up $(IDIR_PPP)/etc/ppp/
install -m0755 ./files/etc/ppp/ip-down $(IDIR_PPP)/etc/ppp/
install -d -m0755 $(IDIR_PPP)/usr/sbin
diff --git a/package/ppp/files/etc/ppp/filter b/package/ppp/files/etc/ppp/filter
new file mode 100644
index 0000000000..ec72a81a01
--- /dev/null
+++ b/package/ppp/files/etc/ppp/filter
@@ -0,0 +1,23 @@
+#
+# Expression: outbound and not icmp[0] != 8 and not tcp[13] & 4 != 0
+#
+19
+48 0 0 0
+21 0 16 1
+40 0 0 2
+21 0 13 33
+48 0 0 13
+21 0 5 1
+40 0 0 10
+69 9 0 8191
+177 0 0 4
+80 0 0 4
+21 6 7 8
+21 0 5 6
+40 0 0 10
+69 3 0 8191
+177 0 0 4
+80 0 0 17
+69 1 0 4
+6 0 0 4
+6 0 0 0
diff --git a/package/ppp/files/ifup.pppoa b/package/ppp/files/ifup.pppoa
index 2ae6019c51..baea25ebf2 100644
--- a/package/ppp/files/ifup.pppoa
+++ b/package/ppp/files/ifup.pppoa
@@ -25,6 +25,7 @@ case "$DEMAND" in
on|1|enabled)
DEMAND=$(nvram get ppp_idletime)
DEMAND=${IDLETIME:+demand idle $IDLETIME}
+ [ -f /etc/ppp/filter ] && DEMAND=${DEMAND:+precompiled-active-filter /etc/ppp/filter $DEMAND}
;;
*) DEMAND="persist";;
esac
diff --git a/package/ppp/files/ifup.pppoe b/package/ppp/files/ifup.pppoe
index d4a79aedd5..1f9cd739c3 100644
--- a/package/ppp/files/ifup.pppoe
+++ b/package/ppp/files/ifup.pppoe
@@ -24,6 +24,7 @@ case "$DEMAND" in
on|1|enabled)
DEMAND=$(nvram get ppp_idletime)
DEMAND=${IDLETIME:+demand idle $IDLETIME}
+ [ -f /etc/ppp/filter ] && DEMAND=${DEMAND:+precompiled-active-filter /etc/ppp/filter $DEMAND}
;;
*) DEMAND="persist";;
esac
diff --git a/package/ppp/patches/310-precompiled_filter.patch b/package/ppp/patches/310-precompiled_filter.patch
new file mode 100644
index 0000000000..df9452c379
--- /dev/null
+++ b/package/ppp/patches/310-precompiled_filter.patch
@@ -0,0 +1,231 @@
+diff -urN ppp.old/pppd/Makefile.linux ppp.dev/pppd/Makefile.linux
+--- ppp.old/pppd/Makefile.linux 2006-03-18 15:58:00.000000000 +0100
++++ ppp.dev/pppd/Makefile.linux 2006-03-18 16:52:01.000000000 +0100
+@@ -50,6 +50,9 @@
+ # and that the kernel driver support PPP packet filtering.
+ #FILTER=y
+
++# Support for precompiled filters
++PRECOMPILED_FILTER=y
++
+ # Uncomment the next line to enable multilink PPP (enabled by default)
+ # Linux distributions: Please leave multilink ENABLED in your builds
+ # of pppd!
+@@ -177,6 +180,14 @@
+ endif
+ endif
+
++ifdef PRECOMPILED_FILTER
++PPPDSRCS += pcap_pcc.c
++HEADERS += pcap_pcc.h
++PPPDOBJS += pcap_pcc.o
++LIBS += $(STAGING_DIR)/usr/lib/libpcap.a
++CFLAGS += -DPPP_FILTER -DPPP_PRECOMPILED_FILTER -I$(STAGING_DIR)/usr/include
++endif
++
+ ifdef HAVE_INET6
+ PPPDSRCS += ipv6cp.c eui64.c
+ HEADERS += ipv6cp.h eui64.h
+diff -urN ppp.old/pppd/demand.c ppp.dev/pppd/demand.c
+--- ppp.old/pppd/demand.c 2006-03-18 15:58:00.000000000 +0100
++++ ppp.dev/pppd/demand.c 2006-03-18 18:09:16.000000000 +0100
+@@ -438,12 +438,14 @@
+ return 0;
+ proto = PPP_PROTOCOL(p);
+ #ifdef PPP_FILTER
++ *p = 1; /* set outbound for the filter rule */
+ if (pass_filter.bf_len != 0
+ && bpf_filter(pass_filter.bf_insns, p, len, len) == 0)
+ return 0;
+ if (active_filter.bf_len != 0
+ && bpf_filter(active_filter.bf_insns, p, len, len) == 0)
+ return 0;
++ *p = 0xff; /* restore original ppp header */
+ #endif
+ for (i = 0; (protp = protocols[i]) != NULL; ++i) {
+ if (protp->protocol < 0xC000 && (protp->protocol & ~0x8000) == proto) {
+diff -urN ppp.old/pppd/options.c ppp.dev/pppd/options.c
+--- ppp.old/pppd/options.c 2006-03-18 15:58:00.000000000 +0100
++++ ppp.dev/pppd/options.c 2006-03-18 18:05:58.000000000 +0100
+@@ -57,14 +57,7 @@
+
+ #ifdef PPP_FILTER
+ #include <pcap.h>
+-/*
+- * DLT_PPP_WITH_DIRECTION is in current libpcap cvs, and should be in
+- * libpcap-0.8.4. Until that is released, use DLT_PPP - but that means
+- * we lose the inbound and outbound qualifiers.
+- */
+-#ifndef DLT_PPP_WITH_DIRECTION
+-#define DLT_PPP_WITH_DIRECTION DLT_PPP
+-#endif
++#include <pcap-bpf.h>
+ #endif
+
+ #include "pppd.h"
+@@ -155,6 +148,13 @@
+ static int loadplugin __P((char **));
+ #endif
+
++#ifdef PPP_PRECOMPILED_FILTER
++#include "pcap_pcc.h"
++static int setprecompiledpassfilter __P((char **));
++static int setprecompiledactivefilter __P((char **));
++#undef PPP_FILTER
++#endif
++
+ #ifdef PPP_FILTER
+ static int setpassfilter __P((char **));
+ static int setactivefilter __P((char **));
+@@ -312,6 +312,14 @@
+ "set filter for active pkts", OPT_PRIO },
+ #endif
+
++#ifdef PPP_PRECOMPILED_FILTER
++ { "precompiled-pass-filter", 1, setprecompiledpassfilter,
++ "set precompiled filter for packets to pass", OPT_PRIO },
++
++ { "precompiled-active-filter", 1, setprecompiledactivefilter,
++ "set precompiled filter for active pkts", OPT_PRIO },
++#endif
++
+ #ifdef MAXOCTETS
+ { "maxoctets", o_int, &maxoctets,
+ "Set connection traffic limit",
+@@ -1447,6 +1455,29 @@
+ return ok;
+ }
+
++#ifdef PPP_PRECOMPILED_FILTER
++/*
++ * setprecompiledpassfilter - Set the pass filter for packets using a
++ * precompiled expression
++ */
++static int
++setprecompiledpassfilter(argv)
++ char **argv;
++{
++ return pcap_pre_compiled (*argv, &pass_filter);
++}
++
++/*
++ * setactivefilter - Set the active filter for packets
++ */
++static int
++setprecompiledactivefilter(argv)
++ char **argv;
++{
++ return pcap_pre_compiled (*argv, &active_filter);
++}
++#endif
++
+ #ifdef PPP_FILTER
+ /*
+ * setpassfilter - Set the pass filter for packets
+@@ -1458,7 +1489,7 @@
+ pcap_t *pc;
+ int ret = 0;
+
+- pc = pcap_open_dead(DLT_PPP_WITH_DIRECTION, 65535);
++ pc = pcap_open_dead(DLT_PPP_PPPD, 65535);
+ if (pcap_compile(pc, &pass_filter, *argv, 1, netmask) == -1) {
+ option_error("error in pass-filter expression: %s\n",
+ pcap_geterr(pc));
+@@ -1479,7 +1510,7 @@
+ pcap_t *pc;
+ int ret = 0;
+
+- pc = pcap_open_dead(DLT_PPP_WITH_DIRECTION, 65535);
++ pc = pcap_open_dead(DLT_PPP_PPPD, 65535);
+ if (pcap_compile(pc, &active_filter, *argv, 1, netmask) == -1) {
+ option_error("error in active-filter expression: %s\n",
+ pcap_geterr(pc));
+diff -urN ppp.old/pppd/pcap_pcc.c ppp.dev/pppd/pcap_pcc.c
+--- ppp.old/pppd/pcap_pcc.c 1970-01-01 01:00:00.000000000 +0100
++++ ppp.dev/pppd/pcap_pcc.c 2006-03-18 16:51:31.000000000 +0100
+@@ -0,0 +1,74 @@
++#include <pcap.h>
++#include <pcap-bpf.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#include <errno.h>
++#include "pppd.h"
++
++int pcap_pre_compiled (char * fname, struct bpf_program *p)
++{
++ char buf[128];
++ int line = 0, size = 0, index=0, ret=1;
++ FILE *f = fopen (fname, "r");
++ if (!f)
++ {
++ option_error("error opening precompiled active-filter '%s': %s",
++ fname, strerror (errno));
++ return 0;
++ }
++ while (fgets (buf, 127, f))
++ {
++ line++;
++ if (*buf == '#')
++ continue;
++ if (size)
++ {
++ /*
++ struct bpf_insn {
++ u_short code;
++ u_char jt;
++ u_char jf;
++ bpf_int32 k;
++ }
++ */
++ struct bpf_insn * insn = & p->bf_insns[index];
++ unsigned code, jt, jf, k;
++ if (sscanf (buf, "%u %u %u %u", &code, &jt, &jf, &k) != 4)
++ {
++ goto err;
++ }
++ insn->code = code;
++ insn->jt = jt;
++ insn->jf = jf;
++ insn->k = k;
++ index++;
++ }
++ else
++ {
++ if (sscanf (buf, "%u", &size) != 1)
++ {
++ goto err;
++ }
++ p->bf_len = size;
++ p->bf_insns = (struct bpf_insn *)
++ malloc (size * sizeof (struct bpf_insn));
++ }
++ }
++ if (size != index)
++ {
++ option_error("error in precompiled active-filter,"
++ " expected %d expressions, got %dn",
++ size, index);
++ ret = 0;
++ }
++ fclose(f);
++ return ret;
++
++err:
++ option_error("error in precompiled active-filter"
++ " expression line %s:%d (wrong size)\n",
++ fname, line);
++ fclose (f);
++ return 0;
++}
+diff -urN ppp.old/pppd/pcap_pcc.h ppp.dev/pppd/pcap_pcc.h
+--- ppp.old/pppd/pcap_pcc.h 1970-01-01 01:00:00.000000000 +0100
++++ ppp.dev/pppd/pcap_pcc.h 2006-03-18 15:59:14.000000000 +0100
+@@ -0,0 +1,7 @@
++#ifndef PCAP_PCC_H
++#define PCAP_PCC_H
++
++#include <pcap.h>
++
++int pcap_pre_compiled (char * fname, struct bpf_program *p);
++#endif /* PCAP_PCC_H */
diff --git a/package/ppp/utils/pfc.c b/package/ppp/utils/pfc.c
new file mode 100644
index 0000000000..5476be170a
--- /dev/null
+++ b/package/ppp/utils/pfc.c
@@ -0,0 +1,51 @@
+/*
+ * Taken from fli4l 3.0
+ * Make sure you compile it against the same libpcap version used in OpenWrt
+ */
+
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <string.h>
+
+#include <linux/types.h>
+#include <linux/ppp_defs.h>
+
+#include <pcap.h>
+#include <pcap-bpf.h>
+
+int main (int argc, char ** argv)
+{
+ pcap_t *pc; /* Fake struct pcap so we can compile expr */
+ struct bpf_program filter; /* Filter program for link-active pkts */
+ u_int32_t netmask=0;
+
+ int dflag = 3;
+ if (argc == 4)
+ {
+ if (!strcmp (argv[1], "-d"))
+ {
+ dflag = atoi (argv[2]);
+ argv += 2;
+ argc -=2;
+ }
+ }
+ if (argc != 2)
+ {
+ printf ("usage; %s [ -d <debug_level> ] expression\n", argv[0]);
+ return 1;
+ }
+
+ pc = pcap_open_dead(DLT_PPP_PPPD, PPP_HDRLEN);
+ if (pcap_compile(pc, &filter, argv[1], 1, netmask) == 0)
+ {
+ printf ("#\n# Expression: %s\n#\n", argv[1]);
+ bpf_dump (&filter, dflag);
+ return 0;
+ }
+ else
+ {
+ printf("error in active-filter expression: %s\n", pcap_geterr(pc));
+ }
+ return 1;
+}
diff --git a/package/pptp/files/ifup.pptp b/package/pptp/files/ifup.pptp
index fe04d97848..9b1ac07c26 100644
--- a/package/pptp/files/ifup.pptp
+++ b/package/pptp/files/ifup.pptp
@@ -23,6 +23,7 @@ case "$DEMAND" in
on|1|enabled)
DEMAND=$(nvram get ppp_idletime)
DEMAND=${IDLETIME:+demand idle $IDLETIME}
+ [ -f /etc/ppp/filter ] && DEMAND=${DEMAND:+precompiled-active-filter /etc/ppp/filter $DEMAND}
;;
*) DEMAND="persist";;
esac