Home | History | Annotate | Download | only in netfilter
      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