Initial commit of vpp code.
[vpp.git] / vpp-japi / japi / vppjni.h
1 /*
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
26 typedef struct {
27     u8 * name;
28     u32 value;
29 } name_sort_t;
30
31 typedef 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
58 typedef 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
86 typedef 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
99 typedef struct {
100   u64 octets;
101   packet_counters_t pkts;
102 } if_counters_t;
103
104 typedef 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
112 typedef 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
179 vppjni_main_t vppjni_main __attribute__((aligned (64)));
180
181
182 static 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
189 static 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
196 static inline void vppjni_unlock (vppjni_main_t * jm)
197 {
198   jm->tag = 0;
199   CLIB_MEMORY_BARRIER();
200   jm->lock = 0;
201 }
202
203 static inline f64 vppjni_time_now (vppjni_main_t *jm)
204 {
205   return clib_time_now (&jm->clib_time);
206 }
207
208 static 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
217 typedef __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
224 void 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)                                  \
229 do {                                            \
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)                               \
238 do {                                            \
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__ */