blob: d2054b77a26ae815782b5ea4e725c5108d6d46df [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;
43 u32 sub_id;
44 u8 sub_dot1ad;
45 u8 sub_number_of_tags;
46 u16 sub_outer_vlan_id;
47 u16 sub_inner_vlan_id;
48 u8 sub_exact_match;
49 u8 sub_default;
50 u8 sub_outer_vlan_id_any;
51 u8 sub_inner_vlan_id_any;
52 u32 vtr_op;
53 u32 vtr_push_dot1q;
54 u32 vtr_tag1;
55 u32 vtr_tag2;
56} sw_interface_details_t;
57
58typedef struct {
59 u8 * interface_name;
60 u32 sw_if_index;
61 /*
62 * Subinterface ID. A number 0-N to uniquely identify
63 * this subinterface under the super interface
64 */
65 u32 sub_id;
66
67 /* 0 = dot1q, 1=dot1ad */
68 u8 sub_dot1ad;
69
70 /* Number of tags 0-2 */
71 u8 sub_number_of_tags;
72 u16 sub_outer_vlan_id;
73 u16 sub_inner_vlan_id;
74 u8 sub_exact_match;
75 u8 sub_default;
76 u8 sub_outer_vlan_id_any;
77 u8 sub_inner_vlan_id_any;
78
79 /* vlan tag rewrite */
80 u32 vtr_op;
81 u32 vtr_push_dot1q;
82 u32 vtr_tag1;
83 u32 vtr_tag2;
84} sw_interface_subif_t;
85
86typedef struct {
87 u64 ip4;
88 u64 ip6;
89 u64 unicast;
90 u64 multicast;
91 u64 broadcast;
92 u64 discard;
93 u64 fifo_full;
94 u64 error;
95 u64 unknown_proto;
96 u64 miss;
97} packet_counters_t;
98
99typedef struct {
100 u64 octets;
101 packet_counters_t pkts;
102} if_counters_t;
103
104typedef struct {
105 u8 valid;
106 u32 sw_if_index;
107 if_counters_t rx;
108 if_counters_t tx;
109} sw_interface_stats_t;
110
111
112typedef struct {
113 /* Context IDs */
114 volatile u32 context_id_sent;
115 volatile u32 context_id_received;
116
117 /* Spinlock */
118 volatile u32 lock;
119 u32 tag;
120
121 /* To recycle pseudo-synchronous message code from vpe_api_test... */
122 volatile u32 result_ready;
123 volatile i32 retval;
124 volatile u8 *shmem_result;
125
126 /* thread cleanup */
127 pthread_key_t cleanup_rx_thread_key;
128 /* attachment of rx thread to java thread */
129 JNIEnv *jenv;
130 JavaVM *jvm;
131 jclass jcls;
132 jmethodID jmtdIfDetails; // interfaceDetails method
133 uword *callback_hash; // map context_id => jobject
134 uword *ping_hash; // map ping context_id => msg type called
135
136 /* Timestamp */
137 clib_time_t clib_time;
138
139 /* connected indication */
140 u8 is_connected;
141
142 /* context -> non-trivial reply hash */
143 uword * reply_hash;
144 u32 saved_reply_count;
145
146 /* interface name map */
147 uword * sw_if_index_by_interface_name;
148
149 /* interface counters */
150 sw_interface_stats_t * sw_if_stats_by_sw_if_index;
151
152 /* interface table */
153 sw_interface_details_t * sw_if_table;
154
155 /* interface indices of responses to one sw_if_dump request */
156 u8 collect_indices;
157 u32 * sw_if_dump_if_indices;
158
159 /* program name, build_dir, git_version */
160 u8 program_name[32];
161 u8 build_directory[256];
162 u8 git_branch[32];
163 u8 build_date[32];
164
165 /* subinterface table */
166 sw_interface_subif_t * sw_if_subif_table;
167
168 /* main heap */
169 u8 * heap;
170
171 /* convenience */
172 unix_shared_memory_queue_t * vl_input_queue;
173 api_main_t * api_main;
174 u32 my_client_index;
175
176 vjbd_main_t vjbd_main;
177} vppjni_main_t;
178
179vppjni_main_t vppjni_main __attribute__((aligned (64)));
180
181
182static inline u32 vppjni_get_context_id (vppjni_main_t * jm)
183{
184 u32 my_context_id;
185 my_context_id = __sync_add_and_fetch (&jm->context_id_sent, 1);
186 return my_context_id;
187}
188
189static inline void vppjni_lock (vppjni_main_t * jm, u32 tag)
190{
191 while (__sync_lock_test_and_set (&jm->lock, 1))
192 ;
193 jm->tag = tag;
194}
195
196static inline void vppjni_unlock (vppjni_main_t * jm)
197{
198 jm->tag = 0;
199 CLIB_MEMORY_BARRIER();
200 jm->lock = 0;
201}
202
203static inline f64 vppjni_time_now (vppjni_main_t *jm)
204{
205 return clib_time_now (&jm->clib_time);
206}
207
208static inline int vppjni_sanity_check (vppjni_main_t * jm)
209{
210 if (!jm->is_connected)
211 return VNET_API_ERROR_NOT_CONNECTED;
212 return 0;
213}
214
215#define __PACKED(x) x __attribute__((packed))
216
217typedef __PACKED(struct _vl_api_generic_reply {
218 u16 _vl_msg_id;
219 u32 context;
220 i32 retval;
221 u8 data[0];
222}) vl_api_generic_reply_t;
223
224void vl_api_generic_reply_handler (vl_api_generic_reply_t *mp);
225
226/* M: construct, but don't yet send a message */
227
228#define M(T,t) \
229do { \
230 jm->result_ready = 0; \
231 mp = vl_msg_api_alloc(sizeof(*mp)); \
232 memset (mp, 0, sizeof (*mp)); \
233 mp->_vl_msg_id = ntohs (VL_API_##T); \
234 mp->client_index = jm->my_client_index; \
235 } while(0);
236
237#define M2(T,t,n) \
238do { \
239 jm->result_ready = 0; \
240 mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \
241 memset (mp, 0, sizeof (*mp)); \
242 mp->_vl_msg_id = ntohs (VL_API_##T); \
243 mp->client_index = jm->my_client_index; \
244 } while(0);
245
246
247/* S: send a message */
248#define S (vl_msg_api_send_shmem (jm->vl_input_queue, (u8 *)&mp))
249
250/* W: wait for results, with timeout */
251#define W \
252 do { \
253 timeout = vppjni_time_now (jm) + 1.0; \
254 \
255 while (vppjni_time_now (jm) < timeout) { \
256 if (jm->result_ready == 1) { \
257 return (jm->retval); \
258 } \
259 } \
260 return -99; \
261} while(0);
262
263/* WNR: wait for results, with timeout (without returning) */
264#define WNR \
265 do { \
266 timeout = vppjni_time_now (jm) + 1.0; \
267 \
268 rv = -99; \
269 while (vppjni_time_now (jm) < timeout) { \
270 if (jm->result_ready == 1) { \
271 rv = (jm->retval); \
272 break; \
273 } \
274 } \
275} while(0);
276
277#endif /* __included_vppjni_h__ */