blob: bc738367bcf35ea506dda71760ff473d65974925 [file] [log] [blame]
Ed Warnickecb9cada2015-12-08 15:45:58 -07001/*
2 * Copyright (c) 2015 Cisco and/or its affiliates.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#ifndef __included_vppjni_h__
16#define __included_vppjni_h__
17
18#include <vnet/vnet.h>
19#include <vnet/ip/ip.h>
20#include <vnet/api_errno.h>
21#include <vlibapi/api.h>
22#include <vlibmemory/api.h>
23#include <jni.h>
24#include <japi/vppjni_bridge_domain.h>
25
26typedef struct {
27 u8 * name;
28 u32 value;
29} name_sort_t;
30
31typedef struct {
32 u8 valid; // used in a vector of sw_interface_details_t
33
34 u8 interface_name[64];
35 u32 sw_if_index;
36 u32 sup_sw_if_index;
37 u32 l2_address_length;
38 u8 l2_address[8];
39 u8 admin_up_down;
40 u8 link_up_down;
41 u8 link_duplex;
42 u8 link_speed;
Pavel84e4ffe2016-02-17 15:10:04 +010043 u16 link_mtu;
Ed Warnickecb9cada2015-12-08 15:45:58 -070044 u32 sub_id;
45 u8 sub_dot1ad;
46 u8 sub_number_of_tags;
47 u16 sub_outer_vlan_id;
48 u16 sub_inner_vlan_id;
49 u8 sub_exact_match;
50 u8 sub_default;
51 u8 sub_outer_vlan_id_any;
52 u8 sub_inner_vlan_id_any;
53 u32 vtr_op;
54 u32 vtr_push_dot1q;
55 u32 vtr_tag1;
56 u32 vtr_tag2;
57} sw_interface_details_t;
58
59typedef struct {
60 u8 * interface_name;
61 u32 sw_if_index;
62 /*
63 * Subinterface ID. A number 0-N to uniquely identify
64 * this subinterface under the super interface
65 */
66 u32 sub_id;
67
68 /* 0 = dot1q, 1=dot1ad */
69 u8 sub_dot1ad;
70
71 /* Number of tags 0-2 */
72 u8 sub_number_of_tags;
73 u16 sub_outer_vlan_id;
74 u16 sub_inner_vlan_id;
75 u8 sub_exact_match;
76 u8 sub_default;
77 u8 sub_outer_vlan_id_any;
78 u8 sub_inner_vlan_id_any;
79
80 /* vlan tag rewrite */
81 u32 vtr_op;
82 u32 vtr_push_dot1q;
83 u32 vtr_tag1;
84 u32 vtr_tag2;
85} sw_interface_subif_t;
86
87typedef struct {
Dave Wallacebf8c15e2015-12-17 20:54:54 -050088 u8 *desc;
89} sw_if_config_t;
90
91typedef struct {
92 u32 ip;
93 u8 prefix_length;
94} ipv4_address_t;
95
96typedef struct {
97 u8 ip[16];
98 u8 prefix_length;
99} ipv6_address_t;
100
101typedef struct {
Ed Warnickecb9cada2015-12-08 15:45:58 -0700102 u64 ip4;
103 u64 ip6;
104 u64 unicast;
105 u64 multicast;
106 u64 broadcast;
107 u64 discard;
108 u64 fifo_full;
109 u64 error;
110 u64 unknown_proto;
111 u64 miss;
112} packet_counters_t;
113
114typedef struct {
115 u64 octets;
116 packet_counters_t pkts;
117} if_counters_t;
118
119typedef struct {
120 u8 valid;
121 u32 sw_if_index;
122 if_counters_t rx;
123 if_counters_t tx;
124} sw_interface_stats_t;
125
Dave Wallacebf8c15e2015-12-17 20:54:54 -0500126typedef struct {
Chris Luke99cb3352016-04-26 10:49:53 -0400127 u8 src_address[16];
128 u8 dst_address[16];
Dave Wallacebf8c15e2015-12-17 20:54:54 -0500129 u32 encap_vrf_id;
130 u32 vni;
131 u32 decap_next_index;
Chris Luke99cb3352016-04-26 10:49:53 -0400132 u8 is_ipv6;
Dave Wallacebf8c15e2015-12-17 20:54:54 -0500133} vxlan_tunnel_details_t;
134
Ed Warnickecb9cada2015-12-08 15:45:58 -0700135
136typedef struct {
137 /* Context IDs */
138 volatile u32 context_id_sent;
139 volatile u32 context_id_received;
140
141 /* Spinlock */
142 volatile u32 lock;
143 u32 tag;
144
Damjan Marion08ff7e02016-01-20 13:45:36 +0100145 /* To recycle pseudo-synchronous message code from vpp_api_test... */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700146 volatile u32 result_ready;
147 volatile i32 retval;
148 volatile u8 *shmem_result;
149
150 /* thread cleanup */
151 pthread_key_t cleanup_rx_thread_key;
152 /* attachment of rx thread to java thread */
153 JNIEnv *jenv;
154 JavaVM *jvm;
Ed Warnickecb9cada2015-12-08 15:45:58 -0700155 uword *callback_hash; // map context_id => jobject
156 uword *ping_hash; // map ping context_id => msg type called
157
158 /* Timestamp */
159 clib_time_t clib_time;
160
161 /* connected indication */
162 u8 is_connected;
163
164 /* context -> non-trivial reply hash */
165 uword * reply_hash;
166 u32 saved_reply_count;
167
168 /* interface name map */
169 uword * sw_if_index_by_interface_name;
170
171 /* interface counters */
172 sw_interface_stats_t * sw_if_stats_by_sw_if_index;
173
174 /* interface table */
175 sw_interface_details_t * sw_if_table;
176
Dave Wallacebf8c15e2015-12-17 20:54:54 -0500177 uword * sw_if_config_by_sw_if_index;
178
Ed Warnickecb9cada2015-12-08 15:45:58 -0700179 /* interface indices of responses to one sw_if_dump request */
180 u8 collect_indices;
181 u32 * sw_if_dump_if_indices;
182
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100183 /* program name, build_dir, version */
Ed Warnickecb9cada2015-12-08 15:45:58 -0700184 u8 program_name[32];
185 u8 build_directory[256];
Damjan Mariona0d4a1a2015-12-12 14:40:59 +0100186 u8 version[32];
Ed Warnickecb9cada2015-12-08 15:45:58 -0700187 u8 build_date[32];
188
189 /* subinterface table */
190 sw_interface_subif_t * sw_if_subif_table;
191
Dave Wallacebf8c15e2015-12-17 20:54:54 -0500192 /* used in ip_address_dump request and response handling */
193 ipv4_address_t *ipv4_addresses;
194 ipv6_address_t *ipv6_addresses;
195 u8 is_ipv6;
196
197 /* used in vxlan_tunnel_dump request and response handling */
198 vxlan_tunnel_details_t *vxlan_tunnel_details;
199
Ed Warnickecb9cada2015-12-08 15:45:58 -0700200 /* main heap */
201 u8 * heap;
202
203 /* convenience */
204 unix_shared_memory_queue_t * vl_input_queue;
205 api_main_t * api_main;
206 u32 my_client_index;
207
208 vjbd_main_t vjbd_main;
209} vppjni_main_t;
210
211vppjni_main_t vppjni_main __attribute__((aligned (64)));
212
213
214static inline u32 vppjni_get_context_id (vppjni_main_t * jm)
215{
216 u32 my_context_id;
217 my_context_id = __sync_add_and_fetch (&jm->context_id_sent, 1);
218 return my_context_id;
219}
220
221static inline void vppjni_lock (vppjni_main_t * jm, u32 tag)
222{
223 while (__sync_lock_test_and_set (&jm->lock, 1))
224 ;
225 jm->tag = tag;
226}
227
228static inline void vppjni_unlock (vppjni_main_t * jm)
229{
230 jm->tag = 0;
231 CLIB_MEMORY_BARRIER();
232 jm->lock = 0;
233}
234
235static inline f64 vppjni_time_now (vppjni_main_t *jm)
236{
237 return clib_time_now (&jm->clib_time);
238}
239
240static inline int vppjni_sanity_check (vppjni_main_t * jm)
241{
242 if (!jm->is_connected)
243 return VNET_API_ERROR_NOT_CONNECTED;
244 return 0;
245}
246
247#define __PACKED(x) x __attribute__((packed))
248
249typedef __PACKED(struct _vl_api_generic_reply {
250 u16 _vl_msg_id;
251 u32 context;
252 i32 retval;
253 u8 data[0];
254}) vl_api_generic_reply_t;
255
256void vl_api_generic_reply_handler (vl_api_generic_reply_t *mp);
257
258/* M: construct, but don't yet send a message */
259
260#define M(T,t) \
261do { \
262 jm->result_ready = 0; \
263 mp = vl_msg_api_alloc(sizeof(*mp)); \
264 memset (mp, 0, sizeof (*mp)); \
265 mp->_vl_msg_id = ntohs (VL_API_##T); \
266 mp->client_index = jm->my_client_index; \
267 } while(0);
268
269#define M2(T,t,n) \
270do { \
271 jm->result_ready = 0; \
272 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
273 memset (mp, 0, sizeof (*mp)); \
274 mp->_vl_msg_id = ntohs (VL_API_##T); \
275 mp->client_index = jm->my_client_index; \
276 } while(0);
277
278
279/* S: send a message */
280#define S (vl_msg_api_send_shmem (jm->vl_input_queue, (u8 *)&mp))
281
282/* W: wait for results, with timeout */
283#define W \
284 do { \
285 timeout = vppjni_time_now (jm) + 1.0; \
286 \
287 while (vppjni_time_now (jm) < timeout) { \
288 if (jm->result_ready == 1) { \
289 return (jm->retval); \
290 } \
291 } \
292 return -99; \
293} while(0);
294
295/* WNR: wait for results, with timeout (without returning) */
296#define WNR \
297 do { \
298 timeout = vppjni_time_now (jm) + 1.0; \
299 \
300 rv = -99; \
301 while (vppjni_time_now (jm) < timeout) { \
302 if (jm->result_ready == 1) { \
303 rv = (jm->retval); \
304 break; \
305 } \
306 } \
307} while(0);
308
309#endif /* __included_vppjni_h__ */