- Create ng_ppp_bypass() function, that prepares a packet

with bypass header, to send it out to userland.
- Use ng_ppp_bypass() in ng_ppp_proto_recv().
- Use ng_ppp_bypass() in ng_ppp_comp_recv() and in
  ng_ppp_crypt_recv() if compression or encryption is
  disabled, respectively.
- Any LCP packet goes directly to ng_ppp_bypass(), instead
  of passing through PPP stack.
- Any non-LCP packet on disabled link is discarded. This
  is behavior defined in RFC.

Submitted by:	Alexander Motin <mav alkar.net>
This commit is contained in:
glebius 2007-01-25 21:16:50 +00:00
parent a11c42b474
commit 0688eeab06

View File

@ -76,7 +76,7 @@
* vjc_ip <- <- vjc_ip
* vjc_comp -> header compression -> vjc_comp
* vjc_uncomp -> -> vjc_uncomp
* vjc_vjip -> -> vjc_vjip
* vjc_vjip ->
* -comp_xmit()-----------hcomp_recv()-
* compress <- compression <- decompress
* compress -> -> decompress
@ -298,6 +298,9 @@ static int ng_ppp_mp_recv(node_p node, item_p item, uint16_t proto,
static int ng_ppp_link_xmit(node_p node, item_p item, uint16_t proto,
uint16_t linkNum);
static int ng_ppp_bypass(node_p node, item_p item, uint16_t proto,
uint16_t linkNum);
static int ng_ppp_check_packet(node_p node);
static void ng_ppp_get_packet(node_p node, struct mbuf **mp);
static int ng_ppp_frag_process(node_p node);
@ -807,6 +810,35 @@ ng_ppp_rcvdata_bypass(hook_p hook, item_p item)
linkNum));
}
static int
ng_ppp_bypass(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
{
const priv_p priv = NG_NODE_PRIVATE(node);
uint16_t hdr[2];
struct mbuf *m;
int error;
if (priv->hooks[HOOK_INDEX_BYPASS] == NULL) {
NG_FREE_ITEM(item);
return (ENXIO);
}
/* Add 4-byte bypass header. */
hdr[0] = htons(linkNum);
hdr[1] = htons(proto);
NGI_GET_M(item, m);
if ((m = ng_ppp_prepend(m, &hdr, 4)) == NULL) {
NG_FREE_ITEM(item);
return (ENOBUFS);
}
NGI_M(item) = m;
/* Send packet out hook. */
NG_FWD_ITEM_HOOK(error, item, priv->hooks[HOOK_INDEX_BYPASS]);
return (error);
}
static int
ng_ppp_proto_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
{
@ -833,29 +865,11 @@ ng_ppp_proto_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
break;
}
if (outHook == NULL && priv->hooks[HOOK_INDEX_BYPASS] != NULL) {
uint16_t hdr[2];
struct mbuf *m;
if (outHook == NULL)
return (ng_ppp_bypass(node, item, proto, linkNum));
hdr[0] = htons(linkNum);
hdr[1] = htons(proto);
NGI_GET_M(item, m);
if ((m = ng_ppp_prepend(m, &hdr, 4)) == NULL) {
NG_FREE_ITEM(item);
return (ENOBUFS);
}
NGI_M(item) = m;
outHook = priv->hooks[HOOK_INDEX_BYPASS];
}
if (outHook != NULL) {
/* Send packet out hook. */
NG_FWD_ITEM_HOOK(error, item, outHook);
} else {
NG_FREE_ITEM(item);
error = ENXIO;
}
/* Send packet out hook. */
NG_FWD_ITEM_HOOK(error, item, outHook);
return (error);
}
@ -936,7 +950,6 @@ ng_ppp_hcomp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
if (priv->conf.enableVJDecompression && priv->vjCompHooked) {
hook_p outHook = NULL;
int error;
switch (proto) {
case PROT_VJCOMP:
@ -948,6 +961,8 @@ ng_ppp_hcomp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
}
if (outHook) {
int error;
/* Send packet out hook. */
NG_FWD_ITEM_HOOK(error, item, outHook);
return (error);
@ -1067,6 +1082,10 @@ ng_ppp_comp_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
NG_FWD_ITEM_HOOK(error, item,
priv->hooks[HOOK_INDEX_DECOMPRESS]);
return (error);
} else if (proto == PROT_COMPD) {
/* Disabled protos MUST be silently discarded, but
* unsupported MUST not. Let user-level decide this. */
return (ng_ppp_bypass(node, item, proto, linkNum));
}
return (ng_ppp_hcomp_recv(node, item, proto, linkNum));
@ -1157,13 +1176,20 @@ ng_ppp_crypt_recv(node_p node, item_p item, uint16_t proto, uint16_t linkNum)
priv->bundleStats.recvFrames++;
priv->bundleStats.recvOctets += NGI_M(item)->m_pkthdr.len;
if (proto == PROT_CRYPTD && priv->conf.enableDecryption &&
priv->hooks[HOOK_INDEX_DECRYPT] != NULL) {
int error;
if (proto == PROT_CRYPTD) {
if (priv->conf.enableDecryption &&
priv->hooks[HOOK_INDEX_DECRYPT] != NULL) {
int error;
/* Send packet out hook. */
NG_FWD_ITEM_HOOK(error, item, priv->hooks[HOOK_INDEX_DECRYPT]);
return (error);
/* Send packet out hook. */
NG_FWD_ITEM_HOOK(error, item,
priv->hooks[HOOK_INDEX_DECRYPT]);
return (error);
} else {
/* Disabled protos MUST be silently discarded, but
* unsupported MUST not. Let user-level decide this. */
return (ng_ppp_bypass(node, item, proto, linkNum));
}
}
return (ng_ppp_comp_recv(node, item, proto, linkNum));
@ -1313,6 +1339,16 @@ ng_ppp_rcvdata(hook_p hook, item_p item)
return (EIO);
}
/* LCP packets must go directly to bypass. */
if (proto >= 0xB000)
return (ng_ppp_bypass(node, item, proto, linkNum));
if (!link->conf.enableLink) {
/* Non-LCP packets are denied on a disabled link. */
NG_FREE_ITEM(item);
return (ENXIO);
}
return (ng_ppp_mp_recv(node, item, proto, linkNum));
}