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 (at) suug.ch> 10 * Copyright (c) 2007 Philip Craig <philipc (at) snapgear.com> 11 * Copyright (c) 2007 Secure Computing Corporation 12 * Copyright (c) 2008 Patrick McHardy <kaber (at) 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 29 static 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 59 static 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 65 char *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 72 enum 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 82 struct nfnl_log *nfnl_log_alloc(void) 83 { 84 return (struct nfnl_log *) nl_object_alloc(&log_obj_ops); 85 } 86 87 void nfnl_log_get(struct nfnl_log *log) 88 { 89 nl_object_get((struct nl_object *) log); 90 } 91 92 void 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 104 void 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 110 int nfnl_log_test_group(const struct nfnl_log *log) 111 { 112 return !!(log->ce_mask & LOG_ATTR_GROUP); 113 } 114 115 uint16_t nfnl_log_get_group(const struct nfnl_log *log) 116 { 117 return log->log_group; 118 } 119 120 void 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 126 int nfnl_log_test_copy_mode(const struct nfnl_log *log) 127 { 128 return !!(log->ce_mask & LOG_ATTR_COPY_MODE); 129 } 130 131 enum nfnl_log_copy_mode nfnl_log_get_copy_mode(const struct nfnl_log *log) 132 { 133 return log->log_copy_mode; 134 } 135 136 void 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 142 int nfnl_log_test_copy_range(const struct nfnl_log *log) 143 { 144 return !!(log->ce_mask & LOG_ATTR_COPY_RANGE); 145 } 146 147 uint32_t nfnl_log_get_copy_range(const struct nfnl_log *log) 148 { 149 return log->log_copy_range; 150 } 151 152 void 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 158 int nfnl_log_test_flush_timeout(const struct nfnl_log *log) 159 { 160 return !!(log->ce_mask & LOG_ATTR_FLUSH_TIMEOUT); 161 } 162 163 uint32_t nfnl_log_get_flush_timeout(const struct nfnl_log *log) 164 { 165 return log->log_flush_timeout; 166 } 167 168 void 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 174 int nfnl_log_test_alloc_size(const struct nfnl_log *log) 175 { 176 return !!(log->ce_mask & LOG_ATTR_ALLOC_SIZE); 177 } 178 179 uint32_t nfnl_log_get_alloc_size(const struct nfnl_log *log) 180 { 181 return log->log_alloc_size; 182 } 183 184 void 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 190 int nfnl_log_test_queue_threshold(const struct nfnl_log *log) 191 { 192 return !!(log->ce_mask & LOG_ATTR_QUEUE_THRESHOLD); 193 } 194 195 uint32_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 */ 205 void 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 211 void 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 217 static struct trans_tbl log_flags[] = { 218 __ADD(NFNL_LOG_FLAG_SEQ, seq) 219 __ADD(NFNL_LOG_FLAG_SEQ_GLOBAL, seq_global) 220 }; 221 222 char *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 227 unsigned int nfnl_log_str2flags(const char *name) 228 { 229 return __str2flags(name, log_flags, ARRAY_SIZE(log_flags)); 230 } 231 232 static 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 257 static 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 266 static 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 274 struct 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