Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ppp: Move PFC decompression to PPP generic layer

Extract "Protocol" field decompression code from transport protocols to
PPP generic layer, where it actually belongs. As a consequence, this
patch fixes incorrect place of PFC decompression in L2TP driver (when
it's not PPPOX_BOUND) and also enables this decompression for other
protocols, like PPPoE.

Protocol field decompression also happens in PPP Multilink Protocol
code and in PPP compression protocols implementations (bsd, deflate,
mppe). It looks like there is no easy way to get rid of that, so it was
decided to leave it as is, but provide those cases with appropriate
comments instead.

Changes in v2:
- Fix the order of checking skb data room and proto decompression
- Remove "inline" keyword from ppp_decompress_proto()
- Don't split line before function name
- Prefix ppp_decompress_proto() function with "__"
- Add ppp_decompress_proto() function with skb data room checks
- Add description for introduced functions
- Fix comments (as per review on mailing list)

Signed-off-by: Sam Protsenko <semen.protsenko@linaro.org>
Reviewed-by: Guillaume Nault <g.nault@alphalink.fr>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Sam Protsenko and committed by
David S. Miller
7fb1b8ca e69fbf31

+62 -24
+7 -7
drivers/net/ppp/ppp_async.c
··· 770 770 { 771 771 struct sk_buff *skb; 772 772 unsigned char *p; 773 - unsigned int len, fcs, proto; 773 + unsigned int len, fcs; 774 774 775 775 skb = ap->rpkt; 776 776 if (ap->state & (SC_TOSS | SC_ESCAPE)) ··· 799 799 goto err; 800 800 p = skb_pull(skb, 2); 801 801 } 802 - proto = p[0]; 803 - if (proto & 1) { 804 - /* protocol is compressed */ 805 - *(u8 *)skb_push(skb, 1) = 0; 806 - } else { 802 + 803 + /* If protocol field is not compressed, it can be LCP packet */ 804 + if (!(p[0] & 0x01)) { 805 + unsigned int proto; 806 + 807 807 if (skb->len < 2) 808 808 goto err; 809 - proto = (proto << 8) + p[1]; 809 + proto = (p[0] << 8) + p[1]; 810 810 if (proto == PPP_LCP) 811 811 async_lcp_peek(ap, p, skb->len, 1); 812 812 }
+51 -3
drivers/net/ppp/ppp_generic.c
··· 1965 1965 ppp_recv_unlock(ppp); 1966 1966 } 1967 1967 1968 + /** 1969 + * __ppp_decompress_proto - Decompress protocol field, slim version. 1970 + * @skb: Socket buffer where protocol field should be decompressed. It must have 1971 + * at least 1 byte of head room and 1 byte of linear data. First byte of 1972 + * data must be a protocol field byte. 1973 + * 1974 + * Decompress protocol field in PPP header if it's compressed, e.g. when 1975 + * Protocol-Field-Compression (PFC) was negotiated. No checks w.r.t. skb data 1976 + * length are done in this function. 1977 + */ 1978 + static void __ppp_decompress_proto(struct sk_buff *skb) 1979 + { 1980 + if (skb->data[0] & 0x01) 1981 + *(u8 *)skb_push(skb, 1) = 0x00; 1982 + } 1983 + 1984 + /** 1985 + * ppp_decompress_proto - Check skb data room and decompress protocol field. 1986 + * @skb: Socket buffer where protocol field should be decompressed. First byte 1987 + * of data must be a protocol field byte. 1988 + * 1989 + * Decompress protocol field in PPP header if it's compressed, e.g. when 1990 + * Protocol-Field-Compression (PFC) was negotiated. This function also makes 1991 + * sure that skb data room is sufficient for Protocol field, before and after 1992 + * decompression. 1993 + * 1994 + * Return: true - decompressed successfully, false - not enough room in skb. 1995 + */ 1996 + static bool ppp_decompress_proto(struct sk_buff *skb) 1997 + { 1998 + /* At least one byte should be present (if protocol is compressed) */ 1999 + if (!pskb_may_pull(skb, 1)) 2000 + return false; 2001 + 2002 + __ppp_decompress_proto(skb); 2003 + 2004 + /* Protocol field should occupy 2 bytes when not compressed */ 2005 + return pskb_may_pull(skb, 2); 2006 + } 2007 + 1968 2008 void 1969 2009 ppp_input(struct ppp_channel *chan, struct sk_buff *skb) 1970 2010 { ··· 2017 1977 } 2018 1978 2019 1979 read_lock_bh(&pch->upl); 2020 - if (!pskb_may_pull(skb, 2)) { 1980 + if (!ppp_decompress_proto(skb)) { 2021 1981 kfree_skb(skb); 2022 1982 if (pch->ppp) { 2023 1983 ++pch->ppp->dev->stats.rx_length_errors; ··· 2114 2074 if (ppp->flags & SC_MUST_COMP && ppp->rstate & SC_DC_FERROR) 2115 2075 goto err; 2116 2076 2077 + /* At this point the "Protocol" field MUST be decompressed, either in 2078 + * ppp_input(), ppp_decompress_frame() or in ppp_receive_mp_frame(). 2079 + */ 2117 2080 proto = PPP_PROTO(skb); 2118 2081 switch (proto) { 2119 2082 case PPP_VJC_COMP: ··· 2288 2245 skb_put(skb, len); 2289 2246 skb_pull(skb, 2); /* pull off the A/C bytes */ 2290 2247 2248 + /* Don't call __ppp_decompress_proto() here, but instead rely on 2249 + * corresponding algo (mppe/bsd/deflate) to decompress it. 2250 + */ 2291 2251 } else { 2292 2252 /* Uncompressed frame - pass to decompressor so it 2293 2253 can update its dictionary if necessary. */ ··· 2336 2290 2337 2291 /* 2338 2292 * Do protocol ID decompression on the first fragment of each packet. 2293 + * We have to do that here, because ppp_receive_nonmp_frame() expects 2294 + * decompressed protocol field. 2339 2295 */ 2340 - if ((PPP_MP_CB(skb)->BEbits & B) && (skb->data[0] & 1)) 2341 - *(u8 *)skb_push(skb, 1) = 0; 2296 + if (PPP_MP_CB(skb)->BEbits & B) 2297 + __ppp_decompress_proto(skb); 2342 2298 2343 2299 /* 2344 2300 * Expand sequence number to 32 bits, making it as close
+4 -5
drivers/net/ppp/ppp_synctty.c
··· 709 709 p = skb_pull(skb, 2); 710 710 } 711 711 712 - /* decompress protocol field if compressed */ 713 - if (p[0] & 1) { 714 - /* protocol is compressed */ 715 - *(u8 *)skb_push(skb, 1) = 0; 716 - } else if (skb->len < 2) 712 + /* PPP packet length should be >= 2 bytes when protocol field is not 713 + * compressed. 714 + */ 715 + if (!(p[0] & 0x01) && skb->len < 2) 717 716 goto err; 718 717 719 718 /* queue the frame to be processed */
-5
drivers/net/ppp/pptp.c
··· 325 325 skb_pull(skb, 2); 326 326 } 327 327 328 - if ((*skb->data) & 1) { 329 - /* protocol is compressed */ 330 - *(u8 *)skb_push(skb, 1) = 0; 331 - } 332 - 333 328 skb->ip_summed = CHECKSUM_NONE; 334 329 skb_set_network_header(skb, skb->head-skb->data); 335 330 ppp_input(&po->chan, skb);
-4
net/l2tp/l2tp_ppp.c
··· 236 236 skb->data[1] == PPP_UI) 237 237 skb_pull(skb, 2); 238 238 239 - /* Decompress protocol field if PFC is enabled */ 240 - if ((*skb->data) & 0x1) 241 - *(u8 *)skb_push(skb, 1) = 0; 242 - 243 239 if (sk->sk_state & PPPOX_BOUND) { 244 240 struct pppox_sock *po; 245 241