Before this commit, if the compression is enabled the, ng_ppp(4)

node would send every outgoing frame to the "compress" hook.
Packets received on the "compress" hook were expected to be
compressed and PROT_COMPD tag was put on them unconditionally.

After this commit an alternative compression mode can be set.
In this mode the node doesn't put the PROT_COMPD, the compressor
should put it itself. This is important for such kind of
compressors, that can submit uncompressed frames.

Before this commit, if the decompression is enabled, the ng_ppp(4)
node would send and incoming frame to the "decompress" hook
only if it has the PROT_COMPD proto tag on it.

After this commit an alternative decompression mode can be set.
In this mode the node sends all the incoming packets to the
decompression hook. This is important for such kind of compressors
that need uncompressed packets too, to keep their library in sync.

These new features will be used in new version of mpd4, and in new
compressor nodes.

Submitted by:	Alexander Motin <mav alkar.net>
This commit is contained in:
Gleb Smirnoff 2006-12-28 13:21:54 +00:00
parent 0a1cf344b7
commit ccb07cc3db
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=165580
2 changed files with 127 additions and 48 deletions

View File

@ -222,7 +222,7 @@ static ng_disconnect_t ng_ppp_disconnect;
/* Helper functions */
static int ng_ppp_input(node_p node, int bypass,
int linkNum, item_p item);
int linkNum, item_p item, int index);
static int ng_ppp_output(node_p node, int bypass, int proto,
int linkNum, item_p item);
static int ng_ppp_mp_input(node_p node, int linkNum, item_p item);
@ -622,7 +622,7 @@ ng_ppp_rcvdata(hook_p hook, item_p item)
/* Dispatch incoming frame (if not enabled, to bypass) */
NGI_M(item) = m; /* put changed m back in item */
return ng_ppp_input(node,
!link->conf.enableLink, linkNum, item);
!link->conf.enableLink, linkNum, item, index);
}
/* Get protocol & check if data allowed from this hook */
@ -674,11 +674,35 @@ ng_ppp_rcvdata(hook_p hook, item_p item)
proto = PROT_VJUNCOMP;
break;
case HOOK_INDEX_COMPRESS:
if (!priv->conf.enableCompression) {
switch (priv->conf.enableCompression) {
case NG_PPP_COMPRESS_FULL:
/*
* In full compression mode sending of uncompressed
* frames is permitted, so compressor must prepend
* actual protocol number.
*/
if (m->m_pkthdr.len < 2) {
NG_FREE_ITEM(item);
return (EINVAL);
}
if (m->m_len < 2 && (m = m_pullup(m, 2)) == NULL) {
NGI_M(item) = NULL; /* don't free twice */
NG_FREE_ITEM(item);
return (ENOBUFS);
}
NGI_M(item) = m; /* m may have changed */
proto = ntohs(mtod(m, uint16_t *)[0]);
m_adj(m, 2);
break;
case NG_PPP_COMPRESS_SIMPLE:
proto = PROT_COMPD;
break;
case NG_PPP_COMPRESS_NONE:
NG_FREE_ITEM(item);
return (ENXIO);
}
proto = PROT_COMPD;
break;
case HOOK_INDEX_ENCRYPT:
if (!priv->conf.enableEncryption) {
@ -781,7 +805,7 @@ ng_ppp_rcvdata(hook_p hook, item_p item)
/* Incoming data */
case HOOK_INDEX_DECRYPT:
case HOOK_INDEX_DECOMPRESS:
return ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item);
return ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item, index);
case HOOK_INDEX_VJC_IP:
outHook = priv->hooks[HOOK_INDEX_INET];
@ -849,7 +873,7 @@ ng_ppp_disconnect(hook_p hook)
* and dispatch accordingly.
*/
static int
ng_ppp_input(node_p node, int bypass, int linkNum, item_p item)
ng_ppp_input(node_p node, int bypass, int linkNum, item_p item, int index)
{
const priv_p priv = NG_NODE_PRIVATE(node);
hook_p outHook = NULL;
@ -881,47 +905,86 @@ ng_ppp_input(node_p node, int bypass, int linkNum, item_p item)
if (bypass)
goto bypass;
/* Check protocol */
switch (proto) {
case PROT_COMPD:
if (priv->conf.enableDecompression)
/*
* In full decompression mode we should pass any packet
* to decompressor for dictionary update.
*/
if ((priv->conf.enableDecompression == NG_PPP_DECOMPRESS_FULL) &&
(index < 0 || index == HOOK_INDEX_DECRYPT)) {
/* Check protocol */
switch (proto) {
case PROT_CRYPTD:
if (priv->conf.enableDecryption)
outHook = priv->hooks[HOOK_INDEX_DECRYPT];
break;
case PROT_MP:
if (priv->conf.enableMultilink &&
linkNum != NG_PPP_BUNDLE_LINKNUM) {
NGI_M(item) = m;
return ng_ppp_mp_input(node, linkNum, item);
}
break;
case PROT_COMPD:
case PROT_VJCOMP:
case PROT_VJUNCOMP:
case PROT_APPLETALK:
case PROT_IPX:
case PROT_IP:
case PROT_IPV6:
if ((m = ng_ppp_addproto(m, proto, 0)) == NULL) {
NG_FREE_ITEM(item);
return (ENOBUFS);
}
outHook = priv->hooks[HOOK_INDEX_DECOMPRESS];
break;
case PROT_CRYPTD:
if (priv->conf.enableDecryption)
outHook = priv->hooks[HOOK_INDEX_DECRYPT];
break;
case PROT_VJCOMP:
if (priv->conf.enableVJDecompression && priv->vjCompHooked)
outHook = priv->hooks[HOOK_INDEX_VJC_COMP];
break;
case PROT_VJUNCOMP:
if (priv->conf.enableVJDecompression && priv->vjCompHooked)
outHook = priv->hooks[HOOK_INDEX_VJC_UNCOMP];
break;
case PROT_MP:
if (priv->conf.enableMultilink
&& linkNum != NG_PPP_BUNDLE_LINKNUM) {
NGI_M(item) = m;
return ng_ppp_mp_input(node, linkNum, item);
break;
}
} else {
/* Check protocol */
switch (proto) {
case PROT_COMPD:
if (priv->conf.enableDecompression)
outHook = priv->hooks[HOOK_INDEX_DECOMPRESS];
break;
case PROT_CRYPTD:
if (priv->conf.enableDecryption)
outHook = priv->hooks[HOOK_INDEX_DECRYPT];
break;
case PROT_VJCOMP:
if (priv->conf.enableVJDecompression &&
priv->vjCompHooked)
outHook = priv->hooks[HOOK_INDEX_VJC_COMP];
break;
case PROT_VJUNCOMP:
if (priv->conf.enableVJDecompression &&
priv->vjCompHooked)
outHook = priv->hooks[HOOK_INDEX_VJC_UNCOMP];
break;
case PROT_MP:
if (priv->conf.enableMultilink &&
linkNum != NG_PPP_BUNDLE_LINKNUM) {
NGI_M(item) = m;
return ng_ppp_mp_input(node, linkNum, item);
}
break;
case PROT_APPLETALK:
if (priv->conf.enableAtalk)
outHook = priv->hooks[HOOK_INDEX_ATALK];
break;
case PROT_IPX:
if (priv->conf.enableIPX)
outHook = priv->hooks[HOOK_INDEX_IPX];
break;
case PROT_IP:
if (priv->conf.enableIP)
outHook = priv->hooks[HOOK_INDEX_INET];
break;
case PROT_IPV6:
if (priv->conf.enableIPv6)
outHook = priv->hooks[HOOK_INDEX_IPV6];
break;
}
break;
case PROT_APPLETALK:
if (priv->conf.enableAtalk)
outHook = priv->hooks[HOOK_INDEX_ATALK];
break;
case PROT_IPX:
if (priv->conf.enableIPX)
outHook = priv->hooks[HOOK_INDEX_IPX];
break;
case PROT_IP:
if (priv->conf.enableIP)
outHook = priv->hooks[HOOK_INDEX_INET];
break;
case PROT_IPV6:
if (priv->conf.enableIPv6)
outHook = priv->hooks[HOOK_INDEX_IPV6];
break;
}
bypass:
@ -1320,7 +1383,8 @@ ng_ppp_frag_process(node_p node)
while (ng_ppp_check_packet(node)) {
ng_ppp_get_packet(node, &m);
if ((item = ng_package_data(m, NG_NOFLAGS)) != NULL)
ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item);
ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item,
~((int)NG_PPP_BUNDLE_LINKNUM));
}
/* Delete dead fragments and try again */
@ -1329,7 +1393,7 @@ ng_ppp_frag_process(node_p node)
ng_ppp_get_packet(node, &m);
if ((item = ng_package_data(m, NG_NOFLAGS)) != NULL)
ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM,
item);
item, ~((int)NG_PPP_BUNDLE_LINKNUM));
}
}
@ -1463,7 +1527,8 @@ ng_ppp_frag_checkstale(node_p node)
/* Deliver packet */
if ((item = ng_package_data(m, NG_NOFLAGS)) != NULL)
ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item);
ng_ppp_input(node, 0, NG_PPP_BUNDLE_LINKNUM, item,
~((int)NG_PPP_BUNDLE_LINKNUM));
}
}

View File

@ -75,6 +75,20 @@
#define NG_PPP_HOOK_LINK_PREFIX "link" /* append decimal link number */
/* Compress hook operation modes */
enum {
NG_PPP_COMPRESS_NONE = 0, /* compression disabled */
NG_PPP_COMPRESS_SIMPLE, /* original operation mode */
NG_PPP_COMPRESS_FULL, /* compressor returns proto */
};
/* Decompress hook operation modes */
enum {
NG_PPP_DECOMPRESS_NONE = 0, /* decompression disabled */
NG_PPP_DECOMPRESS_SIMPLE, /* original operation mode */
NG_PPP_DECOMPRESS_FULL, /* forward any packet to decompressor */
};
/* Netgraph commands */
enum {
NGM_PPP_SET_CONFIG = 1, /* takes struct ng_ppp_node_conf */