]> git.proxmox.com Git - mirror_frr.git/blob - lib/log_filter.c
doc: Add `show ipv6 rpf X:X::X:X` command to docs
[mirror_frr.git] / lib / log_filter.c
1 /*
2 * Logging - Filtered file log target
3 * Copyright (C) 2019 Cumulus Networks, Inc.
4 * Stephen Worley
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the Free
8 * Software Foundation; either version 2 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; see the file COPYING; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 #include <zebra.h>
22
23 #include "frr_pthread.h"
24 #include "log.h"
25
26 static pthread_mutex_t logfilterlock = PTHREAD_MUTEX_INITIALIZER;
27 static char zlog_filters[ZLOG_FILTERS_MAX][ZLOG_FILTER_LENGTH_MAX + 1];
28 static uint8_t zlog_filter_count;
29
30 /*
31 * look for a match on the filter in the current filters,
32 * logfilterlock must be held
33 */
34 static int zlog_filter_lookup(const char *lookup)
35 {
36 for (int i = 0; i < zlog_filter_count; i++) {
37 if (strncmp(lookup, zlog_filters[i], sizeof(zlog_filters[0]))
38 == 0)
39 return i;
40 }
41 return -1;
42 }
43
44 void zlog_filter_clear(void)
45 {
46 frr_with_mutex (&logfilterlock) {
47 zlog_filter_count = 0;
48 }
49 }
50
51 int zlog_filter_add(const char *filter)
52 {
53 frr_with_mutex (&logfilterlock) {
54 if (zlog_filter_count >= ZLOG_FILTERS_MAX)
55 return 1;
56
57 if (zlog_filter_lookup(filter) != -1)
58 /* Filter already present */
59 return -1;
60
61 strlcpy(zlog_filters[zlog_filter_count], filter,
62 sizeof(zlog_filters[0]));
63
64 if (zlog_filters[zlog_filter_count][0] == '\0')
65 /* Filter was either empty or didn't get copied
66 * correctly
67 */
68 return -1;
69
70 zlog_filter_count++;
71 }
72 return 0;
73 }
74
75 int zlog_filter_del(const char *filter)
76 {
77 frr_with_mutex (&logfilterlock) {
78 int found_idx = zlog_filter_lookup(filter);
79 int last_idx = zlog_filter_count - 1;
80
81 if (found_idx == -1)
82 /* Didn't find the filter to delete */
83 return -1;
84
85 /* Adjust the filter array */
86 memmove(zlog_filters[found_idx], zlog_filters[found_idx + 1],
87 (last_idx - found_idx) * sizeof(zlog_filters[0]));
88
89 zlog_filter_count--;
90 }
91 return 0;
92 }
93
94 /* Dump all filters to buffer, delimited by new line */
95 int zlog_filter_dump(char *buf, size_t max_size)
96 {
97 int len = 0;
98
99 frr_with_mutex (&logfilterlock) {
100 for (int i = 0; i < zlog_filter_count; i++) {
101 int ret;
102
103 ret = snprintf(buf + len, max_size - len, " %s\n",
104 zlog_filters[i]);
105 len += ret;
106 if ((ret < 0) || ((size_t)len >= max_size))
107 return -1;
108 }
109 }
110
111 return len;
112 }
113
114 static int search_buf(const char *buf, size_t len)
115 {
116 char *found = NULL;
117
118 frr_with_mutex (&logfilterlock) {
119 for (int i = 0; i < zlog_filter_count; i++) {
120 found = memmem(buf, len, zlog_filters[i],
121 strlen(zlog_filters[i]));
122 if (found != NULL)
123 return 0;
124 }
125 }
126
127 return -1;
128 }
129
130 static void zlog_filterfile_fd(struct zlog_target *zt, struct zlog_msg *msgs[],
131 size_t nmsgs)
132 {
133 struct zlog_msg *msgfilt[nmsgs];
134 size_t i, o = 0;
135 const char *text;
136 size_t text_len;
137
138 for (i = 0; i < nmsgs; i++) {
139 if (zlog_msg_prio(msgs[i]) >= LOG_DEBUG) {
140 text = zlog_msg_text(msgs[i], &text_len);
141 if (search_buf(text, text_len) < 0)
142 continue;
143 }
144 msgfilt[o++] = msgs[i];
145 }
146
147 if (o)
148 zlog_fd(zt, msgfilt, o);
149 }
150
151 void zlog_filterfile_init(struct zlog_cfg_filterfile *zcf)
152 {
153 zlog_file_init(&zcf->parent);
154 zcf->parent.zlog_wrap = zlog_filterfile_fd;
155 }
156
157 void zlog_filterfile_fini(struct zlog_cfg_filterfile *zcf)
158 {
159 zlog_file_fini(&zcf->parent);
160 }