1/* 2 * (C) 2006-2011 by Pablo Neira Ayuso <pablo@netfilter.org> 3 * (C) 2011 by Vyatta Inc. <http://www.vyatta.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19#include "conntrackd.h" 20#include "sync.h" 21#include "log.h" 22#include "cache.h" 23#include "external.h" 24 25#include <libnetfilter_conntrack/libnetfilter_conntrack.h> 26#include <stdlib.h> 27 28static struct cache *external; 29static struct cache *external_exp; 30 31static int external_cache_init(void) 32{ 33 external = cache_create("external", CACHE_T_CT, 34 STATE_SYNC(sync)->external_cache_flags, 35 NULL, &cache_sync_external_ct_ops); 36 if (external == NULL) { 37 dlog(LOG_ERR, "can't allocate memory for the external cache"); 38 return -1; 39 } 40 external_exp = cache_create("external", CACHE_T_EXP, 41 STATE_SYNC(sync)->external_cache_flags, 42 NULL, &cache_sync_external_exp_ops); 43 if (external_exp == NULL) { 44 dlog(LOG_ERR, "can't allocate memory for the external cache"); 45 return -1; 46 } 47 48 return 0; 49} 50 51static void external_cache_close(void) 52{ 53 cache_destroy(external); 54 cache_destroy(external_exp); 55} 56 57static void external_cache_ct_new(struct nf_conntrack *ct) 58{ 59 struct cache_object *obj; 60 int id; 61 62 obj = cache_find(external, ct, &id); 63 if (obj == NULL) { 64retry: 65 obj = cache_object_new(external, ct); 66 if (obj == NULL) 67 return; 68 69 if (cache_add(external, obj, id) == -1) { 70 cache_object_free(obj); 71 return; 72 } 73 } else { 74 cache_del(external, obj); 75 cache_object_free(obj); 76 goto retry; 77 } 78} 79 80static void external_cache_ct_upd(struct nf_conntrack *ct) 81{ 82 cache_update_force(external, ct); 83} 84 85static void external_cache_ct_del(struct nf_conntrack *ct) 86{ 87 struct cache_object *obj; 88 int id; 89 90 obj = cache_find(external, ct, &id); 91 if (obj) { 92 cache_del(external, obj); 93 cache_object_free(obj); 94 } 95} 96 97static void external_cache_ct_dump(int fd, int type) 98{ 99 cache_dump(external, fd, type); 100} 101 102static int external_cache_ct_commit(struct nfct_handle *h, int fd) 103{ 104 return cache_commit(external, h, fd); 105} 106 107static void external_cache_ct_flush(void) 108{ 109 cache_flush(external); 110} 111 112static void external_cache_ct_stats(int fd) 113{ 114 cache_stats(external, fd); 115} 116 117static void external_cache_ct_stats_ext(int fd) 118{ 119 cache_stats_extended(external, fd); 120} 121 122static void external_cache_exp_new(struct nf_expect *exp) 123{ 124 struct cache_object *obj; 125 int id; 126 127 obj = cache_find(external_exp, exp, &id); 128 if (obj == NULL) { 129retry: 130 obj = cache_object_new(external_exp, exp); 131 if (obj == NULL) 132 return; 133 134 if (cache_add(external_exp, obj, id) == -1) { 135 cache_object_free(obj); 136 return; 137 } 138 } else { 139 cache_del(external_exp, obj); 140 cache_object_free(obj); 141 goto retry; 142 } 143} 144 145static void external_cache_exp_upd(struct nf_expect *exp) 146{ 147 cache_update_force(external_exp, exp); 148} 149 150static void external_cache_exp_del(struct nf_expect *exp) 151{ 152 struct cache_object *obj; 153 int id; 154 155 obj = cache_find(external_exp, exp, &id); 156 if (obj) { 157 cache_del(external_exp, obj); 158 cache_object_free(obj); 159 } 160} 161 162static void external_cache_exp_dump(int fd, int type) 163{ 164 cache_dump(external_exp, fd, type); 165} 166 167static int external_cache_exp_commit(struct nfct_handle *h, int fd) 168{ 169 return cache_commit(external_exp, h, fd); 170} 171 172static void external_cache_exp_flush(void) 173{ 174 cache_flush(external_exp); 175} 176 177static void external_cache_exp_stats(int fd) 178{ 179 cache_stats(external_exp, fd); 180} 181 182static void external_cache_exp_stats_ext(int fd) 183{ 184 cache_stats_extended(external_exp, fd); 185} 186 187struct external_handler external_cache = { 188 .init = external_cache_init, 189 .close = external_cache_close, 190 .ct = { 191 .new = external_cache_ct_new, 192 .upd = external_cache_ct_upd, 193 .del = external_cache_ct_del, 194 .dump = external_cache_ct_dump, 195 .commit = external_cache_ct_commit, 196 .flush = external_cache_ct_flush, 197 .stats = external_cache_ct_stats, 198 .stats_ext = external_cache_ct_stats_ext, 199 }, 200 .exp = { 201 .new = external_cache_exp_new, 202 .upd = external_cache_exp_upd, 203 .del = external_cache_exp_del, 204 .dump = external_cache_exp_dump, 205 .commit = external_cache_exp_commit, 206 .flush = external_cache_exp_flush, 207 .stats = external_cache_exp_stats, 208 .stats_ext = external_cache_exp_stats_ext, 209 }, 210}; 211