kernel - Finish implementing PG_RAM / pipelined mmap operation
[dragonfly.git] / contrib / ipfilter / mln_ipl.c
blobb170940e8921af933b4de6f5eecbd8c4e44c2217
1 /*
2 * Copyright (C) 1993-2001 by Darren Reed.
4 * See the IPFILTER.LICENCE file for details on licencing.
5 */
6 /*
7 * 29/12/94 Added code from Marc Huber <huber@fzi.de> to allow it to allocate
8 * its own major char number! Way cool patch!
9 */
12 #include <sys/param.h>
15 * Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
16 * on those hooks. We don't need any special mods with this!
18 #if (defined(NetBSD) && (NetBSD > 199609) && (NetBSD <= 1991011)) || \
19 (defined(NetBSD1_2) && NetBSD1_2 > 1)
20 # define NETBSD_PF
21 #endif
23 #include <sys/systm.h>
24 #include <sys/conf.h>
25 #include <sys/file.h>
26 #include <sys/stat.h>
27 #include <sys/proc.h>
28 #include <sys/uio.h>
29 #include <sys/kernel.h>
30 #include <sys/vnode.h>
31 #include <sys/namei.h>
32 #include <sys/malloc.h>
33 #include <sys/mount.h>
34 #include <sys/exec.h>
35 #include <sys/mbuf.h>
36 #include <net/if.h>
37 #include <netinet/in_systm.h>
38 #include <netinet/in.h>
39 #include <netinet/ip.h>
40 #include <net/route.h>
41 #include <netinet/ip_var.h>
42 #include <netinet/tcp.h>
43 #include <netinet/tcpip.h>
44 #include <sys/lkm.h>
45 #include "ipl.h"
46 #include "ip_compat.h"
47 #include "ip_fil.h"
49 #if !defined(__NetBSD_Version__) || __NetBSD_Version__ < 103050000
50 #define vn_lock(v,f) VOP_LOCK(v)
51 #endif
53 #if !defined(VOP_LEASE) && defined(LEASE_CHECK)
54 #define VOP_LEASE LEASE_CHECK
55 #endif
57 #ifndef MIN
58 #define MIN(a,b) (((a)<(b))?(a):(b))
59 #endif
62 extern int lkmenodev __P((void));
64 #if (NetBSD >= 199706) || (defined(OpenBSD) && (OpenBSD >= 200211))
65 int if_ipl_lkmentry __P((struct lkm_table *, int, int));
66 #else
67 #if defined(OpenBSD)
68 int if_ipl __P((struct lkm_table *, int, int));
69 #else
70 int xxxinit __P((struct lkm_table *, int, int));
71 #endif
72 #endif
73 static int ipl_unload __P((void));
74 static int ipl_load __P((void));
75 static int ipl_remove __P((void));
76 static int iplaction __P((struct lkm_table *, int));
77 static char *ipf_devfiles[] = { IPL_NAME, IPL_NAT, IPL_STATE, IPL_AUTH,
78 NULL };
81 #if (defined(NetBSD1_0) && (NetBSD1_0 > 1)) || \
82 (defined(NetBSD) && (NetBSD <= 1991011) && (NetBSD >= 199511))
83 # if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
84 extern const struct cdevsw ipl_cdevsw;
85 # else
86 struct cdevsw ipldevsw =
88 iplopen, /* open */
89 iplclose, /* close */
90 iplread, /* read */
91 0, /* write */
92 iplioctl, /* ioctl */
93 0, /* stop */
94 0, /* tty */
95 0, /* select */
96 0, /* mmap */
97 NULL /* strategy */
99 # endif
100 #else
101 struct cdevsw ipldevsw =
103 iplopen, /* open */
104 iplclose, /* close */
105 iplread, /* read */
106 (void *)nullop, /* write */
107 iplioctl, /* ioctl */
108 (void *)nullop, /* stop */
109 #ifndef OpenBSD
110 (void *)nullop, /* reset */
111 #endif
112 (void *)NULL, /* tty */
113 (void *)nullop, /* select */
114 (void *)nullop, /* mmap */
115 NULL /* strategy */
117 #endif
118 int ipl_major = 0;
120 #if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
121 MOD_DEV(IPL_VERSION, "ipl", NULL, -1, &ipl_cdevsw, -1);
122 #else
123 MOD_DEV(IPL_VERSION, LM_DT_CHAR, -1, &ipldevsw);
124 #endif
126 extern int vd_unuseddev __P((void));
127 extern struct cdevsw cdevsw[];
128 extern int nchrdev;
131 #if (NetBSD >= 199706) || (defined(OpenBSD) && (OpenBSD >= 200211))
132 int if_ipl_lkmentry(lkmtp, cmd, ver)
133 #else
134 #if defined(OpenBSD)
135 int if_ipl(lkmtp, cmd, ver)
136 #else
137 int xxxinit(lkmtp, cmd, ver)
138 #endif
139 #endif
140 struct lkm_table *lkmtp;
141 int cmd, ver;
143 DISPATCH(lkmtp, cmd, ver, iplaction, iplaction, iplaction);
146 #ifdef OpenBSD
147 int lkmexists __P((struct lkm_table *)); /* defined in /sys/kern/kern_lkm.c */
148 #endif
150 static int iplaction(lkmtp, cmd)
151 struct lkm_table *lkmtp;
152 int cmd;
154 struct lkm_dev *args = lkmtp->private.lkm_dev;
155 int err = 0;
156 #if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000)
157 int i;
158 #endif
160 switch (cmd)
162 case LKM_E_LOAD :
163 if (lkmexists(lkmtp))
164 return EEXIST;
166 #if !defined(__NetBSD__) || (__NetBSD_Version__ < 106080000)
167 for (i = 0; i < nchrdev; i++)
168 if (cdevsw[i].d_open == (dev_type_open((*)))lkmenodev ||
169 cdevsw[i].d_open == iplopen)
170 break;
171 if (i == nchrdev) {
172 printf("IP Filter: No free cdevsw slots\n");
173 return ENODEV;
176 ipl_major = i;
177 args->lkm_offset = i; /* slot in cdevsw[] */
178 #else
179 err = devsw_attach(args->lkm_devname,
180 args->lkm_bdev, &args->lkm_bdevmaj,
181 args->lkm_cdev, &args->lkm_cdevmaj);
182 if (err != 0)
183 return (err);
184 ipl_major = args->lkm_cdevmaj;
185 #endif
186 printf("IP Filter: loaded into slot %d\n", ipl_major);
187 return ipl_load();
188 case LKM_E_UNLOAD :
189 #if defined(__NetBSD__) && (__NetBSD_Version__ >= 106080000)
190 devsw_detach(args->lkm_bdev, args->lkm_cdev);
191 args->lkm_bdevmaj = -1;
192 args->lkm_cdevmaj = -1;
193 #endif
194 err = ipl_unload();
195 if (!err)
196 printf("IP Filter: unloaded from slot %d\n",
197 ipl_major);
198 break;
199 case LKM_E_STAT :
200 break;
201 default:
202 err = EIO;
203 break;
205 return err;
209 static int ipl_remove()
211 char *name;
212 struct nameidata nd;
213 int error, i;
215 for (i = 0; (name = ipf_devfiles[i]); i++) {
216 NDINIT(&nd, DELETE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
217 if ((error = namei(&nd)))
218 return (error);
219 VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
220 #ifdef OpenBSD
221 VOP_LOCK(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY, curproc);
222 #else
223 # if !defined(__NetBSD_Version__) || (__NetBSD_Version__ < 106000000)
224 vn_lock(nd.ni_vp, LK_EXCLUSIVE | LK_RETRY);
225 # endif
226 #endif
227 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
228 (void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
230 return 0;
234 static int ipl_unload()
236 int error = 0;
239 * Unloading - remove the filter rule check from the IP
240 * input/output stream.
242 #if defined(__NetBSD__)
243 error = ipl_disable();
244 #else
245 error = ipldetach();
246 #endif
248 if (!error)
249 error = ipl_remove();
250 return error;
254 static int ipl_load()
256 struct nameidata nd;
257 struct vattr vattr;
258 int error = 0, fmode = S_IFCHR|0600, i;
259 char *name;
262 * XXX Remove existing device nodes prior to creating new ones
263 * XXX using the assigned LKM device slot's major number. In a
264 * XXX perfect world we could use the ones specified by cdevsw[].
266 (void)ipl_remove();
268 error = ipl_enable();
269 if (error)
270 return error;
272 for (i = 0; (name = ipf_devfiles[i]); i++) {
273 NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
274 if ((error = namei(&nd)))
275 return error;
276 if (nd.ni_vp != NULL) {
277 VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
278 if (nd.ni_dvp == nd.ni_vp)
279 vrele(nd.ni_dvp);
280 else
281 vput(nd.ni_dvp);
282 vrele(nd.ni_vp);
283 return (EEXIST);
285 VATTR_NULL(&vattr);
286 vattr.va_type = VCHR;
287 vattr.va_mode = (fmode & 07777);
288 vattr.va_rdev = (ipl_major << 8) | i;
289 VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
290 error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
291 if (error)
292 return error;
294 return error;