diff -urN mpd-3.18.orig/src/iface.c mpd-3.18/src/iface.c --- mpd-3.18.orig/src/iface.c Mon Oct 10 22:23:50 2005 +++ mpd-3.18/src/iface.c Mon Oct 10 22:26:52 2005 @@ -316,9 +316,11 @@ #endif /* Turn on interface traffic flow */ - if (Enabled(&iface->options, IFACE_CONF_TCPMSSFIX)) + if (Enabled(&iface->options, IFACE_CONF_TCPMSSFIX)) { NgFuncConfigBPF(bund, BPF_MODE_MSSFIX); - else + if (gNgTcpMssFix) + NgFuncConfigTCPMSS(bund, MAXMSS(iface->mtu)); + } else NgFuncConfigBPF(bund, BPF_MODE_ON); /* Send any cached packets */ diff -urN mpd-3.18.orig/src/main.c mpd-3.18/src/main.c --- mpd-3.18.orig/src/main.c Mon Oct 10 22:23:50 2005 +++ mpd-3.18/src/main.c Mon Oct 10 22:24:20 2005 @@ -66,6 +66,8 @@ "Show usage information" }, { 0, 't', "tee", "", "Insert ng_tee into netgraph" }, + { 0, 'm', "mssfix", "", + "Use ng_tcpmss instead of internal one" }, }; #define OPTLIST_SIZE (sizeof(OptList) / sizeof(*OptList)) @@ -84,6 +86,7 @@ int gNumLinks; int gNumBundles; int gEnableTee = FALSE; + int gNgTcpMssFix; const char *gConfigFile = CONF_FILE; const char *gConfDirectory = PATH_CONF_DIR; @@ -519,6 +522,9 @@ Usage(EX_NORMAL); case 't': gEnableTee = TRUE; + return(0); + case 'm': + gNgTcpMssFix = TRUE; return(0); default: assert(0); diff -urN mpd-3.18.orig/src/ngfunc.c mpd-3.18/src/ngfunc.c --- mpd-3.18.orig/src/ngfunc.c Mon Oct 10 22:23:50 2005 +++ mpd-3.18/src/ngfunc.c Mon Oct 10 22:24:20 2005 @@ -29,6 +29,7 @@ #include #include #include +#include /* * DEFINITIONS @@ -286,6 +287,22 @@ goto fail; } + if (gNgTcpMssFix) { + /* Add a tcpmss node to the bpf node on the "tcpmssfix" hook */ + snprintf(path, sizeof(path), "%s.%s", MPD_HOOK_PPP, NG_PPP_HOOK_INET); + snprintf(mp.type, sizeof(mp.type), "%s", NG_TCPMSS_NODE_TYPE); + snprintf(mp.ourhook, sizeof(mp.ourhook), "%s", BPF_HOOK_TCPMSS); + snprintf(mp.peerhook, sizeof(mp.peerhook), "%s", BPF_HOOK_TCPMSS); + if (NgSendMsg(b->csock, path, + NGM_GENERIC_COOKIE, NGM_MKPEER, &mp, sizeof(mp)) < 0) { + Log(LG_ERR, ("[%s] can't create %s node: %s", + b->name, NG_TCPMSS_NODE_TYPE, strerror(errno))); + goto fail; + } + /* Initial configuration of ng_tcpmss */ + NgFuncConfigTCPMSS(b, 0); + } + /* Configure bpf(8) node */ NgFuncConfigBPF(b, BPF_MODE_OFF); @@ -576,7 +593,11 @@ snprintf(hp->ifNotMatch, sizeof(hp->ifNotMatch), "%s", BPF_HOOK_IFACE); break; case BPF_MODE_MSSFIX: + if (gNgTcpMssFix) { + snprintf(hp->ifMatch, sizeof(hp->ifMatch), "%s", BPF_HOOK_TCPMSS); + } else { snprintf(hp->ifMatch, sizeof(hp->ifMatch), "%s", BPF_HOOK_MPD); + } snprintf(hp->ifNotMatch, sizeof(hp->ifNotMatch), "%s", BPF_HOOK_IFACE); break; default: @@ -611,13 +632,43 @@ assert(0); } - /* Set new program on the BPF_HOOK_IFACE hook */ + /* Set new program on the BPF_HOOK_MPD hook */ + if (NgSendMsg(b->csock, path, NGM_BPF_COOKIE, + NGM_BPF_SET_PROGRAM, hp, NG_BPF_HOOKPROG_SIZE(hp->bpf_prog_len)) < 0) { + Log(LG_ERR, ("[%s] can't set %s node program: %s", + b->name, NG_BPF_NODE_TYPE, strerror(errno))); + DoExit(EX_ERRDEAD); + } + + if (gNgTcpMssFix) { + /* Configure the hook on the TCPMSS node side of the BPF node */ + memset(&u, 0, sizeof(u)); + snprintf(hp->thisHook, sizeof(hp->thisHook), "%s", BPF_HOOK_TCPMSS); + hp->bpf_prog_len = NOMATCH_PROG_LEN; + memcpy(&hp->bpf_prog, + &gNoMatchProg, NOMATCH_PROG_LEN * sizeof(*gNoMatchProg)); + switch (mode) { + case BPF_MODE_OFF: + case BPF_MODE_DEMAND: + case BPF_MODE_ON: + memset(&hp->ifMatch, 0, sizeof(hp->ifMatch)); + memset(&hp->ifNotMatch, 0, sizeof(hp->ifNotMatch)); + break; + case BPF_MODE_MSSFIX: + snprintf(hp->ifMatch, sizeof(hp->ifMatch), "%s", BPF_HOOK_IFACE); + snprintf(hp->ifNotMatch, sizeof(hp->ifNotMatch), "%s", BPF_HOOK_IFACE); + break; + default: + assert(0); + } + /* Set new program on the BPF_HOOK_TCPMSS hook */ if (NgSendMsg(b->csock, path, NGM_BPF_COOKIE, NGM_BPF_SET_PROGRAM, hp, NG_BPF_HOOKPROG_SIZE(hp->bpf_prog_len)) < 0) { Log(LG_ERR, ("[%s] can't set %s node program: %s", b->name, NG_BPF_NODE_TYPE, strerror(errno))); DoExit(EX_ERRDEAD); } + } } /* @@ -1011,5 +1062,36 @@ buf, strerror(errno))); } +/* + * NgFuncConfigTCPMSS() + * + * Configure the tcpmss node to reduce MSS to given value. + */ +void +NgFuncConfigTCPMSS(Bund b, int maxMSS) +{ + char path[NG_PATHLEN + 1]; + struct ng_tcpmss_config tcpmsscfg; + /* Get absolute path to node */ + if (gEnableTee) + snprintf(path, sizeof(path), "%s:%s.%s.%s", b->iface.ifname, + NG_IFACE_HOOK_INET, NG_TEE_HOOK_RIGHT, BPF_HOOK_TCPMSS); + else + snprintf(path, sizeof(path), "%s:%s.%s", b->iface.ifname, + NG_IFACE_HOOK_INET, BPF_HOOK_TCPMSS); + + /* Send configuration message */ + memset(&tcpmsscfg,0,sizeof(tcpmsscfg)); + snprintf(tcpmsscfg.inHook, sizeof(tcpmsscfg.inHook), "%s", BPF_HOOK_TCPMSS); + snprintf(tcpmsscfg.outHook, sizeof(tcpmsscfg.outHook), "%s", BPF_HOOK_TCPMSS); + tcpmsscfg.maxMSS = maxMSS; + + if (NgSendMsg(bund->csock, path, NGM_TCPMSS_COOKIE, + NGM_TCPMSS_CONFIG, &tcpmsscfg, sizeof(tcpmsscfg)) < 0) { + Log(LG_ERR, ("[%s] can't set %s node program: %s", + b->name, NG_TCPMSS_NODE_TYPE, strerror(errno))); + DoExit(EX_ERRDEAD); + } +} diff -urN mpd-3.18.orig/src/ngfunc.h mpd-3.18/src/ngfunc.h --- mpd-3.18.orig/src/ngfunc.h Tue May 4 22:12:28 2004 +++ mpd-3.18/src/ngfunc.h Mon Oct 10 22:24:20 2005 @@ -26,6 +26,7 @@ #define BPF_HOOK_PPP "ppp" #define BPF_HOOK_IFACE "iface" #define BPF_HOOK_MPD "mpd" + #define BPF_HOOK_TCPMSS "tcpmssfix" #define BPF_MODE_OFF 0 /* no BPF node traffic gets through */ #define BPF_MODE_ON 1 /* normal BPF node traffic flow */ @@ -49,6 +50,7 @@ const char *path2, const char *hook2); extern int NgFuncDisconnect(const char *path, const char *hook); extern int NgFuncShutdownNode(Bund b, const char *label, const char *path); + extern void NgFuncConfigTCPMSS(Bund b, int maxMSS); #endif diff -urN mpd-3.18.orig/src/ppp.h mpd-3.18/src/ppp.h --- mpd-3.18.orig/src/ppp.h Mon Oct 10 22:23:50 2005 +++ mpd-3.18/src/ppp.h Mon Oct 10 22:24:20 2005 @@ -85,6 +85,7 @@ extern int gNumLinks; /* Total number of links */ extern int gNumBundles; /* Total number of bundles */ extern int gEnableTee; /* Insert ng_tee into netgraph */ + extern int gNgTcpMssFix; /* Use ng_tcpmss node */ extern Bund bund; /* Current bundle */ extern Link lnk; /* Current link */