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