PPP, VJ, CCP: rework to fix protocol order

We need to do VJ compression before CCP/MPPE compression and VJ
decompression after CCP/MPPE decompression. This leads to a massive
rewrite of how we currently handled VJ only in the PPPoS lower protocol
handler.

Moved VJ structures from pppos to ppp_pcb because we need them back in
PPP core. This is a bit unfortunate because that's not necessary for
PPPoE or PPPoL2TP, but, hey!. Fixed CCP+MPPE+VJ order.
This commit is contained in:
Sylvain Rochet 2015-04-20 00:10:35 +02:00
parent 33838b8c1c
commit b302cad46d
7 changed files with 80 additions and 153 deletions

View File

@ -370,6 +370,11 @@ struct ppp_pcb_s {
unsigned int :2; /* 2 bit of padding */
#endif /* PPP_IPV6_SUPPORT */
unsigned int lcp_echo_timer_running :1; /* set if a timer is running */
#if VJ_SUPPORT
unsigned int vj_enabled :1; /* Flag indicating VJ compression enabled. */
#else /* VJ_SUPPORT */
unsigned int :1; /* 1 bit of padding */
#endif /* VJ_SUPPORT */
#if CCP_SUPPORT
unsigned int ccp_all_rejected :1; /* we rejected all peer's options */
unsigned int ccp_is_open :1; /* true when CCP is open (currently negotiating) */
@ -382,7 +387,7 @@ struct ppp_pcb_s {
#else /* MPPE_SUPPORT */
unsigned int :1; /* 1 bit of padding */
#endif /* MPPE_SUPPORT */
unsigned int :6; /* 6 bits of padding to round out to 16 bits */
unsigned int :5; /* 5 bits of padding to round out to 16 bits */
#if PPP_AUTH_SUPPORT
/* auth data */
@ -420,6 +425,10 @@ struct ppp_pcb_s {
u8_t num_np_open; /* Number of network protocols which we have opened. */
u8_t num_np_up; /* Number of network protocols which have come up. */
#if VJ_SUPPORT
struct vjcompress vj_comp; /* Van Jacobson compression header. */
#endif /* VJ_SUPPORT */
#if CCP_SUPPORT
fsm ccp_fsm; /* CCP fsm structure */
ccp_options ccp_wantoptions; /* what to request the peer to use */

View File

@ -159,14 +159,8 @@ struct link_callbacks {
void (*send_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp);
/* confire the receive-side characteristics of the PPP interface */
void (*recv_config)(ppp_pcb *pcb, void *ctx, u32_t accm, int pcomp, int accomp);
#if VJ_SUPPORT
/* configure TCP header compression */
void (*vj_config)(ppp_pcb *pcb, void *ctx, int vjcomp, int cidcomp, int maxcid);
#endif /* VJ_SUPPORT */
/* Get and set parameters for the given connection. */
err_t (*ioctl)(ppp_pcb *pcb, void *ctx, int cmd, void *arg);
/* Pass the processed input packet to the appropriate handler. */
err_t (*netif_input)(ppp_pcb *pcb, void *ctx, struct pbuf *p, u16_t protocol);
};
/*

View File

@ -81,19 +81,11 @@ struct pppos_pcb_s {
unsigned int open :1; /* Set if PPPoS is open */
unsigned int pcomp :1; /* Does peer accept protocol compression? */
unsigned int accomp :1; /* Does peer accept addr/ctl compression? */
#if VJ_SUPPORT
unsigned int vj_enabled :1; /* Flag indicating VJ compression enabled. */
#else
unsigned int :1; /* 1 bit of padding */
#endif /* VJ_SUPPORT */
unsigned int :4; /* 4 bits of padding to round out to 8 bits */
unsigned int :5; /* 5 bits of padding to round out to 8 bits */
/* PPPoS rx */
ext_accm in_accm; /* Async-Ctl-Char-Map for input. */
struct pbuf *in_head, *in_tail; /* The input packet. */
#if VJ_SUPPORT
struct vjcompress vj_comp; /* Van Jacobson compression header. */
#endif /* VJ_SUPPORT */
u16_t in_protocol; /* The input protocol code. */
u16_t in_fcs; /* Input Frame Check Sequence value. */
u8_t in_state; /* The input process state. */

View File

@ -473,7 +473,6 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protoc
goto err_rte_drop;
}
#if CCP_SUPPORT
#if MPPE_SUPPORT
/* If MPPE is required, refuse any IP packet until we are able to crypt them. */
if (pcb->settings.require_mppe &&
@ -483,6 +482,34 @@ static err_t ppp_netif_output(struct netif *netif, struct pbuf *pb, u16_t protoc
}
#endif /* MPPE_SUPPORT */
#if VJ_SUPPORT
/*
* Attempt Van Jacobson header compression if VJ is configured and
* this is an IP packet.
*/
if (protocol == PPP_IP && pcb->vj_enabled) {
switch (vj_compress_tcp(&pcb->vj_comp, pb)) {
case TYPE_IP:
/* No change...
protocol = PPP_IP_PROTOCOL; */
break;
case TYPE_COMPRESSED_TCP:
protocol = PPP_VJC_COMP;
break;
case TYPE_UNCOMPRESSED_TCP:
protocol = PPP_VJC_UNCOMP;
break;
default:
PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: bad IP packet\n", pcb->netif->num));
LINK_STATS_INC(link.proterr);
LINK_STATS_INC(link.drop);
snmp_inc_ifoutdiscards(pcb->netif);
return ERR_VAL;
}
}
#endif /* VJ_SUPPORT */
#if CCP_SUPPORT
if (pcb->ccp_is_up) {
#if MPPE_SUPPORT
err_t err;
@ -643,6 +670,10 @@ void ppp_clear(ppp_pcb *pcb) {
(*protp->init)(pcb);
}
#if VJ_SUPPORT
vj_compress_init(&pcb->vj_comp);
#endif /* VJ_SUPPORT */
new_phase(pcb, PPP_PHASE_INITIALIZE);
}
@ -781,15 +812,40 @@ void ppp_input(ppp_pcb *pcb, struct pbuf *pb) {
return;
#endif /* PPP_IPV6_SUPPORT */
#if VJ_SUPPORT
case PPP_VJC_COMP: /* VJ compressed TCP */
/*
* Clip off the VJ header and prepend the rebuilt TCP/IP header and
* pass the result to IP.
*/
PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_comp in pbuf len=%d\n", pcb->netif->num, pb->len));
if (pcb->vj_enabled && vj_uncompress_tcp(&pb, &pcb->vj_comp) >= 0) {
ip4_input(pb, pcb->netif);
return;
}
/* Something's wrong so drop it. */
PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ compressed\n", pcb->netif->num));
break;
case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */
/*
* Process the TCP/IP header for VJ header compression and then pass
* the packet to IP.
*/
PPPDEBUG(LOG_INFO, ("ppp_input[%d]: vj_un in pbuf len=%d\n", pcb->netif->num, pb->len));
if (pcb->vj_enabled && vj_uncompress_uncomp(pb, &pcb->vj_comp) >= 0) {
ip4_input(pb, pcb->netif);
return;
}
/* Something's wrong so drop it. */
PPPDEBUG(LOG_WARNING, ("ppp_input[%d]: Dropping VJ uncompressed\n", pcb->netif->num));
break;
#endif /* VJ_SUPPORT */
default: {
int i;
const struct protent *protp;
/* If callback set, try to pass the input packet to low level protocol */
if (pcb->link_cb->netif_input && pcb->link_cb->netif_input(pcb, pcb->link_ctx_cb, pb, protocol) == ERR_OK) {
return;
}
/*
* Upcall the proper protocol input routine.
*/
@ -1038,9 +1094,11 @@ int cdns(ppp_pcb *pcb, u32_t ns1, u32_t ns2) {
* sifvjcomp - config tcp header compression
*/
int sifvjcomp(ppp_pcb *pcb, int vjcomp, int cidcomp, int maxcid) {
if (pcb->link_cb->vj_config) {
pcb->link_cb->vj_config(pcb, pcb->link_ctx_cb, vjcomp, cidcomp, maxcid);
}
pcb->vj_enabled = vjcomp;
pcb->vj_comp.compressSlot = cidcomp;
pcb->vj_comp.maxSlotIndex = maxcid;
PPPDEBUG(LOG_INFO, ("sifvjcomp[%d]: VJ compress enable=%d slot=%d max slot=%d\n",
pcb->netif->num, vjcomp, cidcomp, maxcid));
return 0;
}
#endif /* VJ_SUPPORT */

View File

@ -157,10 +157,6 @@ static const struct link_callbacks pppoe_callbacks = {
pppoe_netif_output,
NULL,
NULL,
#if VJ_SUPPORT
NULL,
#endif /* VJ_SUPPORT */
NULL,
NULL
};

View File

@ -108,10 +108,6 @@ static const struct link_callbacks pppol2tp_callbacks = {
pppol2tp_netif_output,
NULL,
NULL,
#if VJ_SUPPORT
NULL,
#endif /* VJ_SUPPORT */
NULL,
NULL
};

View File

@ -64,10 +64,6 @@ static err_t pppos_destroy(ppp_pcb *ppp, void *ctx);
static void pppos_send_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp);
static void pppos_recv_config(ppp_pcb *ppp, void *ctx, u32_t accm, int pcomp, int accomp);
static err_t pppos_ioctl(ppp_pcb *pcb, void *ctx, int cmd, void *arg);
#if VJ_SUPPORT
static void pppos_vjc_config(ppp_pcb *ppp, void *ctx, int vjcomp, int cidcomp, int maxcid);
static err_t pppos_netif_input(ppp_pcb *ppp, void *ctx, struct pbuf *p, u16_t protocol);
#endif /* VJ_SUPPORT */
/* Prototypes for procedures local to this file. */
#if PPP_INPROC_IRQ_SAFE
@ -90,15 +86,7 @@ static const struct link_callbacks pppos_callbacks = {
pppos_netif_output,
pppos_send_config,
pppos_recv_config,
#if VJ_SUPPORT
pppos_vjc_config,
#endif /* VJ_SUPPORT */
pppos_ioctl,
#if VJ_SUPPORT
pppos_netif_input
#else /* VJ_SUPPORT */
NULL
#endif /* VJ_SUPPORT */
pppos_ioctl
};
/* PPP's Asynchronous-Control-Character-Map. The mask array is used
@ -264,33 +252,6 @@ pppos_netif_output(ppp_pcb *ppp, void *ctx, struct pbuf *pb, u16_t protocol)
err_t err;
LWIP_UNUSED_ARG(ppp);
#if VJ_SUPPORT
/*
* Attempt Van Jacobson header compression if VJ is configured and
* this is an IP packet.
*/
if (protocol == PPP_IP && pppos->vj_enabled) {
switch (vj_compress_tcp(&pppos->vj_comp, pb)) {
case TYPE_IP:
/* No change...
protocol = PPP_IP_PROTOCOL; */
break;
case TYPE_COMPRESSED_TCP:
protocol = PPP_VJC_COMP;
break;
case TYPE_UNCOMPRESSED_TCP:
protocol = PPP_VJC_UNCOMP;
break;
default:
PPPDEBUG(LOG_WARNING, ("pppos_netif_output[%d]: bad IP packet\n", ppp->netif->num));
LINK_STATS_INC(link.proterr);
LINK_STATS_INC(link.drop);
snmp_inc_ifoutdiscards(ppp->netif);
return ERR_VAL;
}
}
#endif /* VJ_SUPPORT */
/* Grab an output buffer. */
nb = pbuf_alloc(PBUF_RAW, 0, PBUF_POOL);
if (nb == NULL) {
@ -352,10 +313,6 @@ pppos_connect(ppp_pcb *ppp, void *ctx)
/* reset PPPoS control block to its initial state */
memset(&pppos->last_xmit, 0, sizeof(pppos_pcb) - ( (char*)&((pppos_pcb*)0)->last_xmit - (char*)0 ) );
#if PPP_IPV4_SUPPORT && VJ_SUPPORT
vj_compress_init(&pppos->vj_comp);
#endif /* PPP_IPV4_SUPPORT && VJ_SUPPORT */
/*
* Default the in and out accm so that escape and flag characters
* are always escaped.
@ -412,11 +369,6 @@ pppos_listen(ppp_pcb *ppp, void *ctx, struct ppp_addrs *addrs)
ipcp_wo->dnsaddr[0] = ip4_addr_get_u32(&addrs->dns1);
ipcp_wo->dnsaddr[1] = ip4_addr_get_u32(&addrs->dns2);
#endif /* LWIP_DNS */
#if VJ_SUPPORT
vj_compress_init(&pppos->vj_comp);
#endif /* VJ_SUPPORT */
#else /* PPP_IPV4_SUPPORT */
LWIP_UNUSED_ARG(addrs);
#endif /* PPP_IPV4_SUPPORT */
@ -855,76 +807,6 @@ fail:
return ERR_VAL;
}
#if VJ_SUPPORT
static void
pppos_vjc_config(ppp_pcb *ppp, void *ctx, int vjcomp, int cidcomp, int maxcid)
{
pppos_pcb *pppos = (pppos_pcb *)ctx;
#if !PPP_DEBUG
LWIP_UNUSED_ARG(ppp);
#endif /* !PPP_DEBUG */
pppos->vj_enabled = vjcomp;
pppos->vj_comp.compressSlot = cidcomp;
pppos->vj_comp.maxSlotIndex = maxcid;
PPPDEBUG(LOG_INFO, ("pppos_vjc_config[%d]: VJ compress enable=%d slot=%d max slot=%d\n",
ppp->netif->num, vjcomp, cidcomp, maxcid));
}
static err_t
pppos_netif_input(ppp_pcb *ppp, void *ctx, struct pbuf *p, u16_t protocol)
{
int ret;
pppos_pcb *pppos = (pppos_pcb *)ctx;
#if !PPP_DEBUG
LWIP_UNUSED_ARG(ppp);
#endif /* !PPP_DEBUG */
switch(protocol) {
case PPP_VJC_COMP: /* VJ compressed TCP */
if (!pppos->vj_enabled) {
break;
}
/*
* Clip off the VJ header and prepend the rebuilt TCP/IP header and
* pass the result to IP.
*/
PPPDEBUG(LOG_INFO, ("pppos_vjc_comp[%d]: vj_comp in pbuf len=%d\n", ppp->netif->num, p->len));
ret = vj_uncompress_tcp(&p, &pppos->vj_comp);
if (ret >= 0) {
ip4_input(p, pppos->ppp->netif);
return ERR_OK;
}
/* Something's wrong so drop it. */
PPPDEBUG(LOG_WARNING, ("pppos_vjc_comp[%d]: Dropping VJ compressed\n", ppp->netif->num));
break;
case PPP_VJC_UNCOMP: /* VJ uncompressed TCP */
if (!pppos->vj_enabled) {
break;
}
/*
* Process the TCP/IP header for VJ header compression and then pass
* the packet to IP.
*/
PPPDEBUG(LOG_INFO, ("pppos_vjc_uncomp[%d]: vj_un in pbuf len=%d\n", ppp->netif->num, p->len));
ret = vj_uncompress_uncomp(p, &pppos->vj_comp);
if (ret >= 0) {
ip4_input(p, pppos->ppp->netif);
return ERR_OK;
}
/* Something's wrong so drop it. */
PPPDEBUG(LOG_WARNING, ("pppos_vjc_uncomp[%d]: Dropping VJ uncompressed\n", ppp->netif->num));
break;
/* Pass the packet to other handlers */
default: ;
}
return ERR_VAL;
}
#endif /* VJ_SUPPORT */
/*
* Drop the input packet.
*/
@ -955,7 +837,7 @@ pppos_input_drop(pppos_pcb *pppos)
}
pppos_input_free_current_packet(pppos);
#if VJ_SUPPORT
vj_uncompress_err(&pppos->vj_comp);
vj_uncompress_err(&pppos->ppp->vj_comp);
#endif /* VJ_SUPPORT */
LINK_STATS_INC(link.drop);