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