Home | History | Annotate | Line # | Download | only in npf
npf_rproc.c revision 1.2
      1  1.2  rmind /*	$NetBSD: npf_rproc.c,v 1.2 2012/02/20 00:18:20 rmind Exp $	*/
      2  1.1  rmind 
      3  1.1  rmind /*-
      4  1.1  rmind  * Copyright (c) 2009-2012 The NetBSD Foundation, Inc.
      5  1.1  rmind  * All rights reserved.
      6  1.1  rmind  *
      7  1.1  rmind  * This material is based upon work partially supported by The
      8  1.1  rmind  * NetBSD Foundation under a contract with Mindaugas Rasiukevicius.
      9  1.1  rmind  *
     10  1.1  rmind  * Redistribution and use in source and binary forms, with or without
     11  1.1  rmind  * modification, are permitted provided that the following conditions
     12  1.1  rmind  * are met:
     13  1.1  rmind  * 1. Redistributions of source code must retain the above copyright
     14  1.1  rmind  *    notice, this list of conditions and the following disclaimer.
     15  1.1  rmind  * 2. Redistributions in binary form must reproduce the above copyright
     16  1.1  rmind  *    notice, this list of conditions and the following disclaimer in the
     17  1.1  rmind  *    documentation and/or other materials provided with the distribution.
     18  1.1  rmind  *
     19  1.1  rmind  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
     20  1.1  rmind  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     21  1.1  rmind  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     22  1.1  rmind  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
     23  1.1  rmind  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     24  1.1  rmind  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     25  1.1  rmind  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     26  1.1  rmind  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     27  1.1  rmind  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     28  1.1  rmind  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     29  1.1  rmind  * POSSIBILITY OF SUCH DAMAGE.
     30  1.1  rmind  */
     31  1.1  rmind 
     32  1.1  rmind /*
     33  1.1  rmind  * NPF rule procedure interface.
     34  1.1  rmind  */
     35  1.1  rmind 
     36  1.1  rmind #include <sys/cdefs.h>
     37  1.1  rmind __KERNEL_RCSID(0, "$NetBSD");
     38  1.1  rmind 
     39  1.1  rmind #include <sys/param.h>
     40  1.2  rmind #include <sys/types.h>
     41  1.1  rmind 
     42  1.1  rmind #include <sys/atomic.h>
     43  1.1  rmind #include <sys/kmem.h>
     44  1.1  rmind 
     45  1.1  rmind #include "npf_impl.h"
     46  1.1  rmind 
     47  1.1  rmind #define	NPF_RNAME_LEN		16
     48  1.1  rmind 
     49  1.1  rmind /* Rule procedure structure. */
     50  1.1  rmind struct npf_rproc {
     51  1.1  rmind 	/* Name. */
     52  1.1  rmind 	char			rp_name[NPF_RNAME_LEN];
     53  1.1  rmind 	/* Reference count. */
     54  1.1  rmind 	u_int			rp_refcnt;
     55  1.1  rmind 	uint32_t		rp_flags;
     56  1.1  rmind 	/* Normalisation options. */
     57  1.1  rmind 	bool			rp_rnd_ipid;
     58  1.1  rmind 	bool			rp_no_df;
     59  1.1  rmind 	u_int			rp_minttl;
     60  1.1  rmind 	u_int			rp_maxmss;
     61  1.1  rmind 	/* Logging interface. */
     62  1.1  rmind 	u_int			rp_log_ifid;
     63  1.1  rmind };
     64  1.1  rmind 
     65  1.1  rmind npf_rproc_t *
     66  1.1  rmind npf_rproc_create(prop_dictionary_t rpdict)
     67  1.1  rmind {
     68  1.1  rmind 	npf_rproc_t *rp;
     69  1.1  rmind 	const char *rname;
     70  1.1  rmind 
     71  1.2  rmind 	rp = kmem_intr_zalloc(sizeof(npf_rproc_t), KM_SLEEP);
     72  1.1  rmind 	rp->rp_refcnt = 1;
     73  1.1  rmind 
     74  1.1  rmind 	/* Name and flags. */
     75  1.1  rmind 	prop_dictionary_get_cstring_nocopy(rpdict, "name", &rname);
     76  1.1  rmind 	strlcpy(rp->rp_name, rname, NPF_RNAME_LEN);
     77  1.1  rmind 	prop_dictionary_get_uint32(rpdict, "flags", &rp->rp_flags);
     78  1.1  rmind 
     79  1.1  rmind 	/* Logging interface ID (integer). */
     80  1.1  rmind 	prop_dictionary_get_uint32(rpdict, "log-interface", &rp->rp_log_ifid);
     81  1.1  rmind 
     82  1.1  rmind 	/* IP ID randomisation and IP_DF flag cleansing. */
     83  1.1  rmind 	prop_dictionary_get_bool(rpdict, "randomize-id", &rp->rp_rnd_ipid);
     84  1.1  rmind 	prop_dictionary_get_bool(rpdict, "no-df", &rp->rp_no_df);
     85  1.1  rmind 
     86  1.1  rmind 	/* Minimum IP TTL and maximum TCP MSS. */
     87  1.1  rmind 	prop_dictionary_get_uint32(rpdict, "min-ttl", &rp->rp_minttl);
     88  1.1  rmind 	prop_dictionary_get_uint32(rpdict, "max-mss", &rp->rp_maxmss);
     89  1.1  rmind 
     90  1.1  rmind 	return rp;
     91  1.1  rmind }
     92  1.1  rmind 
     93  1.1  rmind void
     94  1.1  rmind npf_rproc_acquire(npf_rproc_t *rp)
     95  1.1  rmind {
     96  1.1  rmind 
     97  1.1  rmind 	atomic_inc_uint(&rp->rp_refcnt);
     98  1.1  rmind }
     99  1.1  rmind 
    100  1.1  rmind void
    101  1.1  rmind npf_rproc_release(npf_rproc_t *rp)
    102  1.1  rmind {
    103  1.1  rmind 
    104  1.1  rmind 	/* Destroy on last reference. */
    105  1.1  rmind 	KASSERT(rp->rp_refcnt > 0);
    106  1.1  rmind 	if (atomic_dec_uint_nv(&rp->rp_refcnt) != 0) {
    107  1.1  rmind 		return;
    108  1.1  rmind 	}
    109  1.2  rmind 	kmem_intr_free(rp, sizeof(npf_rproc_t));
    110  1.1  rmind }
    111  1.1  rmind 
    112  1.1  rmind void
    113  1.1  rmind npf_rproc_run(npf_cache_t *npc, nbuf_t *nbuf, npf_rproc_t *rp, int error)
    114  1.1  rmind {
    115  1.1  rmind 	const uint32_t flags = rp->rp_flags;
    116  1.1  rmind 
    117  1.1  rmind 	KASSERT(rp->rp_refcnt > 0);
    118  1.1  rmind 
    119  1.1  rmind 	/* Normalise the packet, if required. */
    120  1.1  rmind 	if ((flags & NPF_RPROC_NORMALIZE) != 0 && !error) {
    121  1.1  rmind 		(void)npf_normalize(npc, nbuf,
    122  1.1  rmind 		    rp->rp_rnd_ipid, rp->rp_no_df,
    123  1.1  rmind 		    rp->rp_minttl, rp->rp_maxmss);
    124  1.1  rmind 		npf_stats_inc(NPF_STAT_RPROC_NORM);
    125  1.1  rmind 	}
    126  1.1  rmind 
    127  1.1  rmind 	/* Log packet, if required. */
    128  1.1  rmind 	if ((flags & NPF_RPROC_LOG) != 0) {
    129  1.1  rmind 		npf_log_packet(npc, nbuf, rp->rp_log_ifid);
    130  1.1  rmind 		npf_stats_inc(NPF_STAT_RPROC_LOG);
    131  1.1  rmind 	}
    132  1.1  rmind }
    133