]>
Commit | Line | Data |
---|---|---|
58ef912c MM |
1 | /* |
2 | * BIRD Library | |
3 | * | |
206f59df | 4 | * (c) 1998--2004 Martin Mares <mj@ucw.cz> |
58ef912c MM |
5 | * |
6 | * Can be freely distributed and used under the terms of the GNU GPL. | |
7 | */ | |
8 | ||
9 | #ifndef _BIRD_BIRDLIB_H_ | |
10 | #define _BIRD_BIRDLIB_H_ | |
11 | ||
cb530392 | 12 | #include "timer.h" |
0e175f9f | 13 | #include "alloca.h" |
cb530392 | 14 | |
58ef912c MM |
15 | /* Ugly structure offset handling macros */ |
16 | ||
54d70d3e | 17 | #define OFFSETOF(s, i) ((size_t) &((s *)0)->i) |
58ef912c | 18 | #define SKIP_BACK(s, i, p) ((s *)((char *)p - OFFSETOF(s, i))) |
7fdd338c | 19 | #define BIRD_ALIGN(s, a) (((s)+a-1)&~(a-1)) |
18c8241a | 20 | |
c4c63eec MM |
21 | /* Utility macros */ |
22 | ||
41f8bf57 OZ |
23 | #define MIN_(a,b) (((a)<(b))?(a):(b)) |
24 | #define MAX_(a,b) (((a)>(b))?(a):(b)) | |
0e175f9f OZ |
25 | |
26 | #ifndef PARSER | |
1ec52253 OZ |
27 | #undef MIN |
28 | #undef MAX | |
41f8bf57 OZ |
29 | #define MIN(a,b) MIN_(a,b) |
30 | #define MAX(a,b) MAX_(a,b) | |
93e868c7 OZ |
31 | #endif |
32 | ||
5126380b | 33 | #define U64(c) UINT64_C(c) |
47f18ac3 | 34 | #define ABS(a) ((a)>=0 ? (a) : -(a)) |
8d9eef17 | 35 | #define DELTA(a,b) (((a)>=(b))?(a)-(b):(b)-(a)) |
77506349 | 36 | #define ARRAY_SIZE(a) (sizeof(a)/sizeof(*(a))) |
cf3527e2 | 37 | |
4e639744 OZ |
38 | |
39 | /* Bitfield macros */ | |
40 | ||
41 | /* b is u32 array (or ptr), l is size of it in bits (multiple of 32), p is 0..(l-1) */ | |
70945cb6 OZ |
42 | #define BIT32_VAL(p) (((u32) 1) << ((p) % 32)) |
43 | #define BIT32_TEST(b,p) ((b)[(p)/32] & BIT32_VAL(p)) | |
44 | #define BIT32_SET(b,p) ((b)[(p)/32] |= BIT32_VAL(p)) | |
45 | #define BIT32_CLR(b,p) ((b)[(p)/32] &= ~BIT32_VAL(p)) | |
46 | #define BIT32_ZERO(b,l) memset((b), 0, (l)/8) | |
47 | ||
61340248 MM |
48 | #ifndef NULL |
49 | #define NULL ((void *) 0) | |
50 | #endif | |
51 | ||
b655596d OZ |
52 | #ifndef IPV6 |
53 | #define IP_VERSION 4 | |
54 | #else | |
55 | #define IP_VERSION 6 | |
56 | #endif | |
57 | ||
0e175f9f | 58 | |
5da8f82f | 59 | /* Macros for gcc attributes */ |
18c8241a MM |
60 | |
61 | #define NORET __attribute__((noreturn)) | |
206f59df | 62 | #define UNUSED __attribute__((unused)) |
58ef912c | 63 | |
0e175f9f OZ |
64 | |
65 | /* Microsecond time */ | |
66 | ||
67 | typedef s64 btime; | |
68 | ||
41f8bf57 OZ |
69 | #define S_ *1000000 |
70 | #define MS_ *1000 | |
71 | #define US_ *1 | |
0e175f9f OZ |
72 | #define TO_S /1000000 |
73 | #define TO_MS /1000 | |
74 | #define TO_US /1 | |
75 | ||
76 | #ifndef PARSER | |
41f8bf57 OZ |
77 | #define S S_ |
78 | #define MS MS_ | |
79 | #define US US_ | |
0e175f9f OZ |
80 | #endif |
81 | ||
82 | ||
1123e707 OZ |
83 | /* Rate limiting */ |
84 | ||
85 | struct tbf { | |
86 | bird_clock_t timestamp; /* Last update */ | |
87 | u16 count; /* Available tokens */ | |
88 | u16 burst; /* Max number of tokens */ | |
89 | u16 rate; /* Rate of replenishment */ | |
90 | u16 mark; /* Whether last op was limited */ | |
91 | }; | |
92 | ||
93 | /* Default TBF values for rate limiting log messages */ | |
94 | #define TBF_DEFAULT_LOG_LIMITS { .rate = 1, .burst = 5 } | |
95 | ||
96 | void tbf_update(struct tbf *f); | |
97 | ||
98 | static inline int | |
99 | tbf_limit(struct tbf *f) | |
100 | { | |
101 | tbf_update(f); | |
102 | ||
103 | if (!f->count) | |
104 | { | |
105 | f->mark = 1; | |
106 | return 1; | |
107 | } | |
108 | ||
109 | f->count--; | |
110 | f->mark = 0; | |
111 | return 0; | |
112 | } | |
113 | ||
114 | ||
c40e05a0 MM |
115 | /* Logging and dying */ |
116 | ||
0e175f9f OZ |
117 | typedef struct buffer { |
118 | byte *start; | |
119 | byte *pos; | |
120 | byte *end; | |
121 | } buffer; | |
122 | ||
123 | #define STACK_BUFFER_INIT(buf,size) \ | |
124 | do { \ | |
125 | buf.start = alloca(size); \ | |
126 | buf.pos = buf.start; \ | |
127 | buf.end = buf.start + size; \ | |
128 | } while(0) | |
129 | ||
130 | #define LOG_BUFFER_INIT(buf) \ | |
131 | STACK_BUFFER_INIT(buf, LOG_BUFFER_SIZE) | |
132 | ||
133 | #define LOG_BUFFER_SIZE 1024 | |
134 | ||
e98bc2ea | 135 | #define log log_msg |
0e175f9f | 136 | void log_commit(int class, buffer *buf); |
e598853e PT |
137 | void log_msg(const char *msg, ...); |
138 | void log_rl(struct tbf *rl, const char *msg, ...); | |
139 | void die(const char *msg, ...) NORET; | |
140 | void bug(const char *msg, ...) NORET; | |
c40e05a0 MM |
141 | |
142 | #define L_DEBUG "\001" /* Debugging messages */ | |
98e87c86 MM |
143 | #define L_TRACE "\002" /* Protocol tracing */ |
144 | #define L_INFO "\003" /* Informational messages */ | |
145 | #define L_REMOTE "\004" /* Remote protocol errors */ | |
27e993fb MM |
146 | #define L_WARN "\005" /* Local warnings */ |
147 | #define L_ERR "\006" /* Local errors */ | |
148 | #define L_AUTH "\007" /* Authorization failed etc. */ | |
149 | #define L_FATAL "\010" /* Fatal errors */ | |
150 | #define L_BUG "\011" /* BIRD bugs */ | |
18c8241a | 151 | |
e598853e | 152 | void debug(const char *msg, ...); /* Printf to debug output */ |
c40e05a0 MM |
153 | |
154 | /* Debugging */ | |
155 | ||
3cbfcafe | 156 | #if defined(LOCAL_DEBUG) || defined(GLOBAL_DEBUG) |
5222c46c | 157 | #define DBG(x, y...) debug(x, ##y) |
c40e05a0 | 158 | #else |
e68dd11c | 159 | #define DBG(x, y...) do { } while(0) |
c40e05a0 MM |
160 | #endif |
161 | ||
98e87c86 MM |
162 | #ifdef DEBUGGING |
163 | #define ASSERT(x) do { if (!(x)) bug("Assertion `%s' failed at %s:%d", #x, __FILE__, __LINE__); } while(0) | |
164 | #else | |
165 | #define ASSERT(x) do { } while(0) | |
166 | #endif | |
167 | ||
f6519414 MM |
168 | /* Pseudorandom numbers */ |
169 | ||
170 | u32 random_u32(void); | |
171 | ||
58ef912c | 172 | #endif |