Click
Loading...
Searching...
No Matches
llrpc.h
1#ifndef CLICK_LLRPC_H
2#define CLICK_LLRPC_H
3#if CLICK_LINUXMODULE
4# include <click/cxxprotect.h>
5CLICK_CXX_PROTECT
6# include <linux/errno.h>
7# include <linux/ioctl.h>
8# include <asm/uaccess.h>
9CLICK_CXX_UNPROTECT
10# include <click/cxxunprotect.h>
11#elif CLICK_BSDMODULE
12# include <sys/errno.h>
13# include <sys/ioccom.h>
14#else
15# include <errno.h>
16# include <sys/ioctl.h>
17# if HAVE_ASM_IOCTL_H
18# include <asm/ioctl.h>
19# endif
20#endif
21
22/* Click low-level RPC interface */
23
24/* Ioctl numbers are not consistent across platforms unless you #define
25 HAVE_PORTABLE_LLRPC. */
26#define _CLICK_NET_IOC_VOID 0x20000000
27#define _CLICK_NET_IOC_OUT 0x40000000
28#define _CLICK_NET_IOC_IN 0x80000000
29#if HAVE_PORTABLE_LLRPC || !defined(__linux__)
30# define _CLICK_IOC_VOID _CLICK_NET_IOC_VOID
31# define _CLICK_IOC_OUT _CLICK_NET_IOC_OUT
32# define _CLICK_IOC_IN _CLICK_NET_IOC_IN
33#else
34# define _CLICK_IOC_VOID (_IOC_NONE << _IOC_DIRSHIFT)
35# define _CLICK_IOC_OUT (_IOC_READ << _IOC_DIRSHIFT)
36# define _CLICK_IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT)
37#endif
38#define _CLICK_IOC_BASE_MASK 0x0FFFFFFF
39#define _CLICK_IOC_SAFE 0x00008000
40#define _CLICK_IOC_FLAT 0x00004000
41#define _CLICK_IOC_SIZE(io) ((io) >> 16 & 0xFFF)
42
43/* _CLICK_IO[S]: data transfer direction unknown, pass pointer unchanged;
44 _CLICK_IOR[S]: data of specified size sent from kernel to user;
45 _CLICK_IOW[S]: data of specified size sent from user to kernel;
46 _CLICK_IOWR[S]: data of specified size transferred in both directions. */
47
48/* "Non-safe" LLRPCs will not be performed in parallel with other LLRPCs or
49 handlers. They will also block the router threads. */
50#define _CLICK_IOX(d, n, sz) ((d) | ((sz) << 16) | (n))
51#define _CLICK_IO(n) _CLICK_IOX(_CLICK_IOC_VOID, (n), 0)
52#define _CLICK_IOR(n, sz) _CLICK_IOX(_CLICK_IOC_OUT, (n), (sz))
53#define _CLICK_IOW(n, sz) _CLICK_IOX(_CLICK_IOC_IN, (n), (sz))
54#define _CLICK_IOWR(n, sz) _CLICK_IOX(_CLICK_IOC_IN|_CLICK_IOC_OUT, (n), (sz))
55
56/* "Safe" LLRPCs may be performed in parallel with read handlers and other
57 safe LLRPCs, but not with write handlers or unsafe LLRPCs. They will not
58 block the router threads. */
59#define _CLICK_IOS(n) _CLICK_IOX(_CLICK_IOC_VOID|_CLICK_IOC_SAFE, (n), 0)
60#define _CLICK_IORS(n, sz) _CLICK_IOX(_CLICK_IOC_OUT|_CLICK_IOC_SAFE, (n), (sz))
61#define _CLICK_IOWS(n, sz) _CLICK_IOX(_CLICK_IOC_IN|_CLICK_IOC_SAFE, (n), (sz))
62#define _CLICK_IOWRS(n, sz) _CLICK_IOX(_CLICK_IOC_IN|_CLICK_IOC_OUT|_CLICK_IOC_SAFE, (n), (sz))
63
64/* "Flat" LLRPCs do not contain pointers -- all data read or written is
65 contained in the size. They can be safe or unsafe. */
66#define _CLICK_IORF(n, sz) _CLICK_IOX(_CLICK_IOC_OUT|_CLICK_IOC_FLAT, (n), (sz))
67#define _CLICK_IOWF(n, sz) _CLICK_IOX(_CLICK_IOC_IN|_CLICK_IOC_FLAT, (n), (sz))
68#define _CLICK_IOWRF(n, sz) _CLICK_IOX(_CLICK_IOC_IN|_CLICK_IOC_OUT|_CLICK_IOC_FLAT, (n), (sz))
69#define _CLICK_IORSF(n, sz) _CLICK_IOX(_CLICK_IOC_OUT|_CLICK_IOC_SAFE|_CLICK_IOC_FLAT, (n), (sz))
70#define _CLICK_IOWSF(n, sz) _CLICK_IOX(_CLICK_IOC_IN|_CLICK_IOC_SAFE|_CLICK_IOC_FLAT, (n), (sz))
71#define _CLICK_IOWRSF(n, sz) _CLICK_IOX(_CLICK_IOC_IN|_CLICK_IOC_OUT|_CLICK_IOC_SAFE|_CLICK_IOC_FLAT, (n), (sz))
72
73#define CLICK_LLRPC_PROXY _CLICK_IO(0)
74#define CLICK_LLRPC_GET_RATE _CLICK_IOWRSF(1, 4)
75#define CLICK_LLRPC_GET_RATES _CLICK_IOS(2)
76#define CLICK_LLRPC_GET_COUNT _CLICK_IOWRSF(3, 4)
77#define CLICK_LLRPC_GET_COUNTS _CLICK_IOS(4)
78#define CLICK_LLRPC_GET_SWITCH _CLICK_IORSF(5, 4)
79#define CLICK_LLRPC_SET_SWITCH _CLICK_IOWF(6, 4)
80#define CLICK_LLRPC_MAP_IPADDRESS _CLICK_IOWRF(7, 4)
81#define CLICK_LLRPC_IPREWRITER_MAP_TCP _CLICK_IOWRF(8, 12)
82#define CLICK_LLRPC_IPREWRITER_MAP_UDP _CLICK_IOWRF(9, 12)
83#define CLICK_LLRPC_IPRATEMON_LEVEL_FWD_AVG _CLICK_IO(10)
84#define CLICK_LLRPC_IPRATEMON_LEVEL_REV_AVG _CLICK_IO(11)
85#define CLICK_LLRPC_IPRATEMON_FWD_N_REV_AVG _CLICK_IO(12)
86#define CLICK_LLRPC_IPRATEMON_SET_ANNO_LEVEL _CLICK_IO(13)
87#define CLICK_IOC_TOUSERDEVICE_GET_MULTI _CLICK_IOS(15)
88#define CLICK_IOC_TOUSERDEVICE_SET_MULTI _CLICK_IOS(16)
89#define CLICK_LLRPC_RAW_HANDLER _CLICK_IOS(17)
90#define CLICK_LLRPC_ABANDON_HANDLER _CLICK_IOS(18)
91#define CLICK_LLRPC_CALL_HANDLER _CLICK_IO(19)
92
93struct click_llrpc_proxy_st {
94 void* proxied_handler; /* const Router::Handler* */
95 uint32_t proxied_command;
96 void* proxied_data;
97};
98
99#define CLICK_LLRPC_COUNTS_SIZE 8
100struct click_llrpc_counts_st {
101 uint32_t n;
102 uint32_t keys[CLICK_LLRPC_COUNTS_SIZE];
103 uint32_t values[CLICK_LLRPC_COUNTS_SIZE];
104};
105
106#define CLICK_LLRPC_CALL_HANDLER_FLAG_RAW 1
107struct click_llrpc_call_handler_st {
108 int flags;
109 size_t errorlen;
110 void *errorbuf;
111};
112
113/* data manipulation */
114
115#if CLICK_USERLEVEL || CLICK_MINIOS
116
117# define CLICK_LLRPC_GET_DATA(local, remote, size) (memcpy(local, remote, size), 0)
118# define CLICK_LLRPC_PUT_DATA(remote, local, size) (memcpy(remote, local, size), 0)
119# define CLICK_LLRPC_GET(local_obj, remote_addr) (memcpy(&(local_obj), remote_addr, sizeof(local_obj)), 0)
120# define CLICK_LLRPC_PUT(remote_addr, local_obj) (memcpy(remote_addr, &(local_obj), sizeof(local_obj)), 0)
121
122#elif CLICK_LINUXMODULE
123
124# ifdef __cplusplus
125# define __CLICK_LLRPC_CAST(x) reinterpret_cast< x >
126# else
127# define __CLICK_LLRPC_CAST(x) (x)
128# endif
129
130# define __CLICK_LLRPC_GENERIC_GET_DATA(local, remote, size) \
131 (copy_from_user(local, remote, size) > 0 ? -EFAULT : 0)
132# define __CLICK_LLRPC_CONSTANT_GET_DATA(local, remote, size) \
133 (size == 1 ? get_user(*__CLICK_LLRPC_CAST(unsigned char *)(local), __CLICK_LLRPC_CAST(unsigned char *)(remote)) \
134 : (size == 2 ? get_user(*__CLICK_LLRPC_CAST(unsigned short *)(local), __CLICK_LLRPC_CAST(unsigned short *)(remote)) \
135 : (size == 4 ? get_user(*__CLICK_LLRPC_CAST(unsigned *)(local), __CLICK_LLRPC_CAST(unsigned *)(remote)) \
136 : __CLICK_LLRPC_GENERIC_GET_DATA(local, remote, size))))
137
138# define __CLICK_LLRPC_GENERIC_PUT_DATA(remote, local, size) \
139 (copy_to_user(remote, local, size) > 0 ? -EFAULT : 0)
140# define __CLICK_LLRPC_CONSTANT_PUT_DATA(remote, local, size) \
141 (size == 1 ? put_user(*__CLICK_LLRPC_CAST(const unsigned char *)(local), __CLICK_LLRPC_CAST(unsigned char *)(remote)) \
142 : (size == 2 ? put_user(*__CLICK_LLRPC_CAST(const unsigned short *)(local), __CLICK_LLRPC_CAST(unsigned short *)(remote)) \
143 : (size == 4 ? put_user(*__CLICK_LLRPC_CAST(const unsigned *)(local), __CLICK_LLRPC_CAST(unsigned *)(remote)) \
144 : __CLICK_LLRPC_GENERIC_PUT_DATA(remote, local, size))))
145
146# define CLICK_LLRPC_GET_DATA(local, remote, size) \
147 (__builtin_constant_p(size) && size <= 4 \
148 ? __CLICK_LLRPC_CONSTANT_GET_DATA(local, remote, size) \
149 : __CLICK_LLRPC_GENERIC_GET_DATA(local, remote, size))
150# define CLICK_LLRPC_PUT_DATA(remote, local, size) \
151 (__builtin_constant_p(size) && size <= 4 \
152 ? __CLICK_LLRPC_CONSTANT_PUT_DATA(remote, local, size) \
153 : __CLICK_LLRPC_GENERIC_PUT_DATA(remote, local, size))
154
155# define CLICK_LLRPC_GET(local_obj, remote_addr) \
156 get_user((local_obj), (remote_addr))
157# define CLICK_LLRPC_PUT(remote_addr, local_obj) \
158 put_user((local_obj), (remote_addr))
159
160#elif CLICK_BSDMODULE
161
162/*
163 * XXX LLRPC isn't implemented for BSD yet.
164 */
165
166# define CLICK_LLRPC_GET_DATA(local, remote, size) ((void)(local), (void)(remote), (void)(size), -EFAULT)
167# define CLICK_LLRPC_PUT_DATA(remote, local, size) ((void)(local), (void)(remote), (void)(size), -EFAULT)
168# define CLICK_LLRPC_GET(local_obj, remote_addr) ((void)(local_obj), (void)(remote_addr), -EFAULT)
169# define CLICK_LLRPC_PUT(remote_addr, local_obj) ((void)(local_obj), (void)(remote_addr), -EFAULT)
170
171#endif
172
173/* CLICK_NTOH_LLRPC: portable LLRPC numbers to host LLRPC numbers */
174/* CLICK_HTON_LLRPC: host LLRPC numbers to portable LLRPC numbers */
175/* both macros are only suitable for integer constants and the like */
176#if _CLICK_IOC_VOID != _CLICK_NET_IOC_VOID || _CLICK_IOC_OUT != _CLICK_NET_IOC_OUT || _CLICK_IOC_IN != _CLICK_NET_IOC_IN
177# define CLICK_LLRPC_NTOH(command) \
178 (((command) & _CLICK_NET_IOC_VOID ? _CLICK_IOC_VOID : 0) \
179 | ((command) & _CLICK_NET_IOC_OUT ? _CLICK_IOC_OUT : 0) \
180 | ((command) & _CLICK_NET_IOC_IN ? _CLICK_IOC_IN : 0) \
181 | ((command) & _CLICK_IOC_BASE_MASK))
182# define CLICK_LLRPC_HTON(command) \
183 (((command) & _CLICK_IOC_VOID ? _CLICK_NET_IOC_VOID : 0) \
184 | ((command) & _CLICK_IOC_OUT ? _CLICK_NET_IOC_OUT : 0) \
185 | ((command) & _CLICK_IOC_IN ? _CLICK_NET_IOC_IN : 0) \
186 | ((command) & _CLICK_IOC_BASE_MASK))
187#else
188# define CLICK_LLRPC_NTOH(command) (command)
189# define CLICK_LLRPC_HTON(command) (command)
190#endif
191
192/* sanity checks */
193#ifdef __FreeBSD__
194# if _CLICK_IOC_VOID != IOC_VOID || _CLICK_IOC_OUT != IOC_OUT || _CLICK_IOC_IN != IOC_IN
195# error "bad _CLICK_IOC constants"
196# endif
197#endif
198#endif