1/* 2 * lib/netfilter/log_obj.c Netfilter Log Object 3 * 4 * This library is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU Lesser General Public 6 * License as published by the Free Software Foundation version 2.1 7 * of the License. 8 * 9 * Copyright (c) 2003-2008 Thomas Graf <tgraf@suug.ch> 10 * Copyright (c) 2007 Philip Craig <philipc@snapgear.com> 11 * Copyright (c) 2007 Secure Computing Corporation 12 * Copyright (c) 2008 Patrick McHardy <kaber@trash.net> 13 */ 14 15#include <netlink-local.h> 16#include <netlink/netfilter/nfnl.h> 17#include <netlink/netfilter/log.h> 18 19/** @cond SKIP */ 20#define LOG_ATTR_GROUP (1UL << 0) 21#define LOG_ATTR_COPY_MODE (1UL << 1) 22#define LOG_ATTR_COPY_RANGE (1UL << 3) 23#define LOG_ATTR_FLUSH_TIMEOUT (1UL << 4) 24#define LOG_ATTR_ALLOC_SIZE (1UL << 5) 25#define LOG_ATTR_QUEUE_THRESHOLD (1UL << 6) 26 27/** @endcond */ 28 29static void nfnl_log_dump(struct nl_object *a, struct nl_dump_params *p) 30{ 31 struct nfnl_log *log = (struct nfnl_log *) a; 32 char buf[64]; 33 34 nl_new_line(p); 35 36 if (log->ce_mask & LOG_ATTR_GROUP) 37 nl_dump(p, "group=%u ", log->log_group); 38 39 if (log->ce_mask & LOG_ATTR_COPY_MODE) 40 nl_dump(p, "copy_mode=%s ", 41 nfnl_log_copy_mode2str(log->log_copy_mode, 42 buf, sizeof(buf))); 43 44 if (log->ce_mask & LOG_ATTR_COPY_RANGE) 45 nl_dump(p, "copy_range=%u ", log->log_copy_range); 46 47 if (log->ce_mask & LOG_ATTR_FLUSH_TIMEOUT) 48 nl_dump(p, "flush_timeout=%u ", log->log_flush_timeout); 49 50 if (log->ce_mask & LOG_ATTR_ALLOC_SIZE) 51 nl_dump(p, "alloc_size=%u ", log->log_alloc_size); 52 53 if (log->ce_mask & LOG_ATTR_QUEUE_THRESHOLD) 54 nl_dump(p, "queue_threshold=%u ", log->log_queue_threshold); 55 56 nl_dump(p, "\n"); 57} 58 59static struct trans_tbl copy_modes[] = { 60 __ADD(NFNL_LOG_COPY_NONE, none) 61 __ADD(NFNL_LOG_COPY_META, meta) 62 __ADD(NFNL_LOG_COPY_PACKET, packet) 63}; 64 65char *nfnl_log_copy_mode2str(enum nfnl_log_copy_mode copy_mode, char *buf, 66 size_t len) 67{ 68 return __type2str(copy_mode, buf, len, copy_modes, 69 ARRAY_SIZE(copy_modes)); 70} 71 72enum nfnl_log_copy_mode nfnl_log_str2copy_mode(const char *name) 73{ 74 return __str2type(name, copy_modes, ARRAY_SIZE(copy_modes)); 75} 76 77/** 78 * @name Allocation/Freeing 79 * @{ 80 */ 81 82struct nfnl_log *nfnl_log_alloc(void) 83{ 84 return (struct nfnl_log *) nl_object_alloc(&log_obj_ops); 85} 86 87void nfnl_log_get(struct nfnl_log *log) 88{ 89 nl_object_get((struct nl_object *) log); 90} 91 92void nfnl_log_put(struct nfnl_log *log) 93{ 94 nl_object_put((struct nl_object *) log); 95} 96 97/** @} */ 98 99/** 100 * @name Attributes 101 * @{ 102 */ 103 104void nfnl_log_set_group(struct nfnl_log *log, uint16_t group) 105{ 106 log->log_group = group; 107 log->ce_mask |= LOG_ATTR_GROUP; 108} 109 110int nfnl_log_test_group(const struct nfnl_log *log) 111{ 112 return !!(log->ce_mask & LOG_ATTR_GROUP); 113} 114 115uint16_t nfnl_log_get_group(const struct nfnl_log *log) 116{ 117 return log->log_group; 118} 119 120void nfnl_log_set_copy_mode(struct nfnl_log *log, enum nfnl_log_copy_mode mode) 121{ 122 log->log_copy_mode = mode; 123 log->ce_mask |= LOG_ATTR_COPY_MODE; 124} 125 126int nfnl_log_test_copy_mode(const struct nfnl_log *log) 127{ 128 return !!(log->ce_mask & LOG_ATTR_COPY_MODE); 129} 130 131enum nfnl_log_copy_mode nfnl_log_get_copy_mode(const struct nfnl_log *log) 132{ 133 return log->log_copy_mode; 134} 135 136void nfnl_log_set_copy_range(struct nfnl_log *log, uint32_t copy_range) 137{ 138 log->log_copy_range = copy_range; 139 log->ce_mask |= LOG_ATTR_COPY_RANGE; 140} 141 142int nfnl_log_test_copy_range(const struct nfnl_log *log) 143{ 144 return !!(log->ce_mask & LOG_ATTR_COPY_RANGE); 145} 146 147uint32_t nfnl_log_get_copy_range(const struct nfnl_log *log) 148{ 149 return log->log_copy_range; 150} 151 152void nfnl_log_set_flush_timeout(struct nfnl_log *log, uint32_t timeout) 153{ 154 log->log_flush_timeout = timeout; 155 log->ce_mask |= LOG_ATTR_FLUSH_TIMEOUT; 156} 157 158int nfnl_log_test_flush_timeout(const struct nfnl_log *log) 159{ 160 return !!(log->ce_mask & LOG_ATTR_FLUSH_TIMEOUT); 161} 162 163uint32_t nfnl_log_get_flush_timeout(const struct nfnl_log *log) 164{ 165 return log->log_flush_timeout; 166} 167 168void nfnl_log_set_alloc_size(struct nfnl_log *log, uint32_t alloc_size) 169{ 170 log->log_alloc_size = alloc_size; 171 log->ce_mask |= LOG_ATTR_ALLOC_SIZE; 172} 173 174int nfnl_log_test_alloc_size(const struct nfnl_log *log) 175{ 176 return !!(log->ce_mask & LOG_ATTR_ALLOC_SIZE); 177} 178 179uint32_t nfnl_log_get_alloc_size(const struct nfnl_log *log) 180{ 181 return log->log_alloc_size; 182} 183 184void nfnl_log_set_queue_threshold(struct nfnl_log *log, uint32_t threshold) 185{ 186 log->log_queue_threshold = threshold; 187 log->ce_mask |= LOG_ATTR_QUEUE_THRESHOLD; 188} 189 190int nfnl_log_test_queue_threshold(const struct nfnl_log *log) 191{ 192 return !!(log->ce_mask & LOG_ATTR_QUEUE_THRESHOLD); 193} 194 195uint32_t nfnl_log_get_queue_threshold(const struct nfnl_log *log) 196{ 197 return log->log_queue_threshold; 198} 199 200/* We don't actually use the flags for anything yet since the 201 * nfnetlog_log interface truly sucks - it only contains the 202 * flag value, but not mask, so we would have to make assumptions 203 * about the supported flags. 204 */ 205void nfnl_log_set_flags(struct nfnl_log *log, unsigned int flags) 206{ 207 log->log_flags |= flags; 208 log->log_flag_mask |= flags; 209} 210 211void nfnl_log_unset_flags(struct nfnl_log *log, unsigned int flags) 212{ 213 log->log_flags &= ~flags; 214 log->log_flag_mask |= flags; 215} 216 217static struct trans_tbl log_flags[] = { 218 __ADD(NFNL_LOG_FLAG_SEQ, seq) 219 __ADD(NFNL_LOG_FLAG_SEQ_GLOBAL, seq_global) 220}; 221 222char *nfnl_log_flags2str(unsigned int flags, char *buf, size_t len) 223{ 224 return __flags2str(flags, buf, len, log_flags, ARRAY_SIZE(log_flags)); 225} 226 227unsigned int nfnl_log_str2flags(const char *name) 228{ 229 return __str2flags(name, log_flags, ARRAY_SIZE(log_flags)); 230} 231 232static int nfnl_log_compare(struct nl_object *_a, struct nl_object *_b, 233 uint32_t attrs, int flags) 234{ 235 struct nfnl_log *a = (struct nfnl_log *) _a; 236 struct nfnl_log *b = (struct nfnl_log *) _b; 237 int diff = 0; 238 239#define NFNL_LOG_DIFF(ATTR, EXPR) \ 240 ATTR_DIFF(attrs, LOG_ATTR_##ATTR, a, b, EXPR) 241#define NFNL_LOG_DIFF_VAL(ATTR, FIELD) \ 242 NFNL_LOG_DIFF(ATTR, a->FIELD != b->FIELD) 243 244 diff |= NFNL_LOG_DIFF_VAL(GROUP, log_group); 245 diff |= NFNL_LOG_DIFF_VAL(COPY_MODE, log_copy_mode); 246 diff |= NFNL_LOG_DIFF_VAL(COPY_RANGE, log_copy_range); 247 diff |= NFNL_LOG_DIFF_VAL(FLUSH_TIMEOUT, log_flush_timeout); 248 diff |= NFNL_LOG_DIFF_VAL(ALLOC_SIZE, log_alloc_size); 249 diff |= NFNL_LOG_DIFF_VAL(QUEUE_THRESHOLD, log_queue_threshold); 250 251#undef NFNL_LOG_DIFF 252#undef NFNL_LOG_DIFF_VAL 253 254 return diff; 255} 256 257static struct trans_tbl nfnl_log_attrs[] = { 258 __ADD(LOG_ATTR_GROUP, group) 259 __ADD(LOG_ATTR_COPY_MODE, copy_mode) 260 __ADD(LOG_ATTR_COPY_RANGE, copy_range) 261 __ADD(LOG_ATTR_FLUSH_TIMEOUT, flush_timeout) 262 __ADD(LOG_ATTR_ALLOC_SIZE, alloc_size) 263 __ADD(LOG_ATTR_QUEUE_THRESHOLD, queue_threshold) 264}; 265 266static char *nfnl_log_attrs2str(int attrs, char *buf, size_t len) 267{ 268 return __flags2str(attrs, buf, len, nfnl_log_attrs, 269 ARRAY_SIZE(nfnl_log_attrs)); 270} 271 272/** @} */ 273 274struct nl_object_ops log_obj_ops = { 275 .oo_name = "netfilter/log", 276 .oo_size = sizeof(struct nfnl_log), 277 .oo_dump = { 278 [NL_DUMP_LINE] = nfnl_log_dump, 279 [NL_DUMP_DETAILS] = nfnl_log_dump, 280 [NL_DUMP_STATS] = nfnl_log_dump, 281 }, 282 .oo_compare = nfnl_log_compare, 283 .oo_attrs2str = nfnl_log_attrs2str, 284 .oo_id_attrs = LOG_ATTR_GROUP, 285}; 286 287/** @} */ 288