Subject: kern/20844: No way to Load PPP compressors as kernel modules
To: None <gnats-bugs@gnats.netbsd.org>
From: Iain Hibbert <plunky@rya-online.net>
List: netbsd-bugs
Date: 03/21/2003 11:39:32
>Number:         20844
>Category:       kern
>Synopsis:       PPP Compressors cannot be loaded as LKM
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Sat Mar 22 02:25:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:     Iain Hibbert
>Release:        NetBSD 1.5.1
>Organization:
iain
>Environment:
	
System: NetBSD galant 1.5.2 NetBSD 1.5.2 (GALANT) #2: Tue Mar 18 11:05:27 GMT 2003 plunky@galant:/usr/home/plunky/src/sys/arch/i386/compile/GALANT i386

(but, -current is no different)

>Description:
PPP Compressors (bsd-comp and deflate are included with NetBSD) are not loadable
compressor modules, so you must compile them into the kernel and cannot add them
later..

I include a patch below to make compressor loaders for several compressors - this
works for 1.5.2, but I'm not really sure if the interface has changed at all in
later versions.. the ppp interface has not.

this patch modifies:

	src/sys/net/if_ppp.c
	src/sys/net/ppp-comp.h
	src/sys/lkm/Makefile

and installs a new directory with subdirectories:

	src/sys/lkm/compress
	src/sys/lkm/compress/Makefile
	src/sys/lkm/compress/Makefile.inc
	src/sys/lkm/compress/bsdcomp
	src/sys/lkm/compress/bsdcomp/Makefile
	src/sys/lkm/compress/bsdcomp/lkminit_bsdcomp.c
	src/sys/lkm/compress/deflate
	src/sys/lkm/compress/deflate/Makefile
	src/sys/lkm/compress/deflate/lkminit_deflate.c

the mods to net/if_ppp.c and net/ppp-comp.h (wrt to PPP_COMPRESSORS_MAX) might
not be the right way to do it, the value of 8 that is currently hardcoded
means that 7 compressors can be loaded (its a NULL terminated list)

I donate this code copyright to NetBSD Foundation, but would like my name
to stay on it.. please add the usual licence/copyright information.

	
>How-To-Repeat:
run netbsd
	
>Fix:
	

diff -C 4 -P /usr/src/sys/net/if_ppp.c src/sys/net/if_ppp.c
*** /usr/src/sys/net/if_ppp.c	Thu Feb 27 22:07:50 2003
--- src/sys/net/if_ppp.c	Thu Feb 27 22:08:17 2003
***************
*** 213,219 ****
  extern struct compressor ppp_bsd_compress;
  extern struct compressor ppp_deflate, ppp_deflate_draft;
  
! struct compressor *ppp_compressors[8] = {
  #if DO_BSD_COMPRESS && defined(PPP_BSDCOMP)
      &ppp_bsd_compress,
  #endif
--- 213,219 ----
  extern struct compressor ppp_bsd_compress;
  extern struct compressor ppp_deflate, ppp_deflate_draft;
  
! struct compressor *ppp_compressors[PPP_COMPRESSORS_MAX] = {
  #if DO_BSD_COMPRESS && defined(PPP_BSDCOMP)
      &ppp_bsd_compress,
  #endif
diff -C 4 -P /usr/src/sys/net/ppp-comp.h src/sys/net/ppp-comp.h
*** /usr/src/sys/net/ppp-comp.h	Thu Feb 27 22:07:58 2003
--- src/sys/net/ppp-comp.h	Thu Feb 27 22:09:54 2003
***************
*** 52,57 ****
--- 52,64 ----
  #define DO_PREDICTOR_2	0
  
  /*
+  * How many entries to make available in the compressors table
+  */
+ #ifndef PPP_COMPRESSORS_MAX
+ #define PPP_COMPRESSORS_MAX	8
+ #endif
+ 
+ /*
   * Structure giving methods for compression/decompression.
   */
  #ifdef PACKETPTR
diff -C 4 -P -r /usr/src/sys/lkm/Makefile src/sys/lkm/Makefile
*** /usr/src/sys/lkm/Makefile	Wed Feb 12 20:54:16 2003
--- src/sys/lkm/Makefile	Sun Mar  2 18:42:58 2003
***************
*** 1,5 ****
  # $NetBSD: Makefile,v 1.3 1999/03/26 22:32:03 scottr Exp $
  
! SUBDIR=	arch compat netinet vfs
  
  .include <bsd.subdir.mk>
--- 1,5 ----
  # $NetBSD: Makefile,v 1.3 1999/03/26 22:32:03 scottr Exp $
  
! SUBDIR=	arch compat netinet vfs compress
  
  .include <bsd.subdir.mk>
diff -C 4 -P -r /usr/src/sys/lkm/compress/Makefile src/sys/lkm/compress/Makefile
*** /usr/src/sys/lkm/compress/Makefile	Thu Jan  1 01:00:00 1970
--- src/sys/lkm/compress/Makefile	Tue Mar 18 10:28:19 2003
***************
*** 0 ****
--- 1,4 ----
+ 
+ SUBDIR=	bsdcomp deflate
+ 
+ .include <bsd.subdir.mk>
diff -C 4 -P -r /usr/src/sys/lkm/compress/Makefile.inc src/sys/lkm/compress/Makefile.inc
*** /usr/src/sys/lkm/compress/Makefile.inc	Thu Jan  1 01:00:00 1970
--- src/sys/lkm/compress/Makefile.inc	Sun Mar  2 18:40:43 2003
***************
*** 0 ****
--- 1,4 ----
+ 
+ S!=	cd ${.CURDIR}/../../..;pwd
+ 
+ .include "../Makefile.inc"
diff -C 4 -P -r /usr/src/sys/lkm/compress/bsdcomp/Makefile src/sys/lkm/compress/bsdcomp/Makefile
*** /usr/src/sys/lkm/compress/bsdcomp/Makefile	Thu Jan  1 01:00:00 1970
--- src/sys/lkm/compress/bsdcomp/Makefile	Sun Mar  2 19:19:35 2003
***************
*** 0 ****
--- 1,11 ----
+ 
+ .include "../Makefile.inc"
+ 
+ .PATH: $S/net
+ 
+ CPPFLAGS+=-DDO_BSD_COMPRESS=1
+ MKMAN=	no
+ KMOD=	bsdcomp
+ SRCS=	lkminit_bsdcomp.c bsd-comp.c
+ 
+ .include <bsd.kmod.mk>
diff -C 4 -P -r /usr/src/sys/lkm/compress/bsdcomp/lkminit_bsdcomp.c src/sys/lkm/compress/bsdcomp/lkminit_bsdcomp.c
*** /usr/src/sys/lkm/compress/bsdcomp/lkminit_bsdcomp.c	Thu Jan  1 01:00:00 1970
--- src/sys/lkm/compress/bsdcomp/lkminit_bsdcomp.c	Sun Mar  2 18:40:52 2003
***************
*** 0 ****
--- 1,89 ----
+ /*
+  * lkminit_bsdcomp.c
+  *
+  * written by Iain Hibbert <plunky@rya-online.net>
+  */
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/conf.h>
+ #include <sys/exec.h>
+ #include <sys/lkm.h>
+ #include <sys/file.h>
+ #include <sys/errno.h>
+ #include <sys/mbuf.h>
+ 
+ #define PACKETPTR 	struct mbuf *
+ #include <net/ppp_defs.h>
+ #include <net/ppp-comp.h>
+ 
+ extern struct compressor *ppp_compressors[];
+ extern struct compressor ppp_bsd_compress;
+ 
+ static int bsdcomp_handle __P((struct lkm_table *lkmtp, int cmd));
+ int bsdcomp_lkmentry __P((struct lkm_table *lkmtp, int cmd, int ver));
+ 
+ MOD_MISC("bsdcomp")
+ 
+ static int
+ bsdcomp_handle(lkmtp, cmd)
+     struct lkm_table *lkmtp;
+     int cmd;
+ {
+     int	i = 0;
+ 
+     switch(cmd) {
+     case LKM_E_LOAD:
+ 	/*
+ 	 * Load the compressor into the master table in the first available
+ 	 * slot, unless we already have a CI_BSD_COMPRESS type listed. Leave
+ 	 * a space at the end, its a NULL terminated list.
+ 	 */
+ 
+ 	while(ppp_compressors[i]) {
+ 	    if (ppp_compressors[i]->compress_proto == CI_BSD_COMPRESS)
+ 		return EEXIST; /* either me, or the in-kernel version */
+ 
+ 	    if (++i == PPP_COMPRESSORS_MAX - 1)
+ 		return ENFILE;	/* no room */
+ 	}
+ 
+ 	ppp_compressors[i] = &ppp_bsd_compress;
+ 	break;
+ 
+     case LKM_E_UNLOAD:
+ 
+ 	/*
+ 	 * Find the first instance of CI_BSD_COMPRESS in the table, and
+ 	 * unload it. If this instance was not mine, Somebody has been
+ 	 * Playing With Fire, and will likely Get Burnt.
+ 	 */
+ 	while (ppp_compressors[i]->compress_proto != CI_BSD_COMPRESS)
+ 	    i++;
+ 
+ 	while (ppp_compressors[i] && i < (PPP_COMPRESSORS_MAX - 1)) {
+ 	    ppp_compressors[i] = ppp_compressors[i + 1];
+ 	    i++;
+ 	}
+ 	ppp_compressors[i] = NULL;
+ 	break;
+ 
+     case LKM_E_STAT:
+ 	break;
+ 
+     default:
+ 	return EINVAL;
+     }
+ 
+     return 0;	/* success */
+ }
+ 
+ /*
+  * the module entry point.
+  */
+ int
+ bsdcomp_lkmentry(lkmtp, cmd, ver)
+     struct lkm_table *lkmtp;
+     int cmd, ver;
+ {
+     DISPATCH(lkmtp, cmd, ver, bsdcomp_handle, bsdcomp_handle, bsdcomp_handle)
+ }
diff -C 4 -P -r /usr/src/sys/lkm/compress/deflate/Makefile src/sys/lkm/compress/deflate/Makefile
*** /usr/src/sys/lkm/compress/deflate/Makefile	Thu Jan  1 01:00:00 1970
--- src/sys/lkm/compress/deflate/Makefile	Sun Mar  2 19:19:39 2003
***************
*** 0 ****
--- 1,11 ----
+ 
+ .include "../Makefile.inc"
+ 
+ .PATH:	$S/net
+ 
+ CPPFLAGS+=-DDO_DEFLATE=1
+ MKMAN=	no
+ KMOD=	deflate
+ SRCS=	lkminit_deflate.c ppp-deflate.c zlib.c
+ 
+ .include <bsd.kmod.mk>
diff -C 4 -P -r /usr/src/sys/lkm/compress/deflate/lkminit_deflate.c src/sys/lkm/compress/deflate/lkminit_deflate.c
*** /usr/src/sys/lkm/compress/deflate/lkminit_deflate.c	Thu Jan  1 01:00:00 1970
--- src/sys/lkm/compress/deflate/lkminit_deflate.c	Sun Mar  2 18:40:52 2003
***************
*** 0 ****
--- 1,100 ----
+ /*
+  * lkminit_deflate.c
+  *
+  * written by Iain Hibbert <plunky@rya-online.net>
+  */
+ #include <sys/param.h>
+ #include <sys/systm.h>
+ #include <sys/conf.h>
+ #include <sys/exec.h>
+ #include <sys/lkm.h>
+ #include <sys/file.h>
+ #include <sys/errno.h>
+ #include <sys/mbuf.h>
+ 
+ #define PACKETPTR 	struct mbuf *
+ #include <net/ppp_defs.h>
+ #include <net/ppp-comp.h>
+ 
+ extern struct compressor *ppp_compressors[];
+ extern struct compressor ppp_deflate;
+ extern struct compressor ppp_deflate_draft;
+ 
+ static int deflate_handle __P((struct lkm_table *lkmtp, int cmd));
+ int deflate_lkmentry __P((struct lkm_table *lkmtp, int cmd, int ver));
+ 
+ MOD_MISC("deflate")
+ 
+ static int
+ deflate_handle(lkmtp, cmd)
+     struct lkm_table *lkmtp;
+     int cmd;
+ {
+     int	i = 0;
+     static int qty;	/* how many compressors we loaded */
+ 
+     switch(cmd) {
+     case LKM_E_LOAD:
+ 	/*
+ 	 * Load the compressor into the first available slot in the
+ 	 * kernel compressors table, unless there is a CI_DEFLATE
+ 	 * compressor already listed. The table is a NULL terminated
+ 	 * list, so leave a space at the end.
+ 	 */
+ 
+ 	while(ppp_compressors[i]) {
+ 	    if (ppp_compressors[i]->compress_proto == CI_DEFLATE)
+ 		return EEXIST; /* either me, or the in-kernel version */
+ 
+ 	    if (++i == PPP_COMPRESSORS_MAX - 1)
+ 		return ENFILE;	/* no room */
+ 	}
+ 	ppp_compressors[i] = &ppp_deflate;
+ 	qty = 1;
+ 
+ 	/*
+ 	 * and add deflate_draft if we have any room left
+ 	 */
+ 	if (++i < PPP_COMPRESSORS_MAX - 1) {
+ 	    ppp_compressors[i] = &ppp_deflate_draft;
+ 	    qty = 2;
+ 	}
+ 	break;
+ 
+     case LKM_E_UNLOAD:
+ 
+ 	/*
+ 	 * Find the first instance of CI_DEFLATE in the table, and
+ 	 * unload it. If this instance was not mine, Somebody has been
+ 	 * Playing With Fire, and will likely Get Burnt.
+ 	 */
+ 	while (ppp_compressors[i]->compress_proto != CI_DEFLATE)
+ 	    i++;
+ 
+ 	while (ppp_compressors[i] && i < (PPP_COMPRESSORS_MAX - qty)) {
+ 	    ppp_compressors[i] = ppp_compressors[i + qty];
+ 	    i++;
+ 	}
+ 	ppp_compressors[i] = NULL;
+ 	break;
+ 
+     case LKM_E_STAT:
+ 	break;
+ 
+     default:
+ 	return EINVAL;
+     }
+ 
+     return 0;	/* success */
+ }
+ 
+ /*
+  * the module entry point.
+  */
+ int
+ deflate_lkmentry(lkmtp, cmd, ver)
+     struct lkm_table *lkmtp;
+     int cmd, ver;
+ {
+     DISPATCH(lkmtp, cmd, ver, deflate_handle, deflate_handle, deflate_handle)
+ }
>Release-Note:
>Audit-Trail:
>Unformatted: