VXLAN over IPv6.
[vpp.git] / vpp-api / java / 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     u16 link_mtu;
44     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
59 typedef 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
87 typedef struct {
88     u8 *desc;
89 } sw_if_config_t;
90
91 typedef struct {
92     u32 ip;
93     u8 prefix_length;
94 } ipv4_address_t;
95
96 typedef struct {
97     u8 ip[16];
98     u8 prefix_length;
99 } ipv6_address_t;
100
101 typedef struct {
102   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
114 typedef struct {
115   u64 octets;
116   packet_counters_t pkts;
117 } if_counters_t;
118
119 typedef 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
126 typedef struct {
127     u8 src_address[16];
128     u8 dst_address[16];
129     u32 encap_vrf_id;
130     u32 vni;
131     u32 decap_next_index;
132     u8 is_ipv6;
133 } vxlan_tunnel_details_t;
134
135
136 typedef 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
145   /* To recycle pseudo-synchronous message code from vpp_api_test... */
146   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;
155   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
177   uword * sw_if_config_by_sw_if_index;
178
179   /* interface indices of responses to one sw_if_dump request */
180   u8 collect_indices;
181   u32 * sw_if_dump_if_indices;
182
183   /* program name, build_dir, version */
184   u8 program_name[32];
185   u8 build_directory[256];
186   u8 version[32];
187   u8 build_date[32];
188
189   /* subinterface table */
190   sw_interface_subif_t * sw_if_subif_table;
191
192   /* 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
200   /* 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
211 vppjni_main_t vppjni_main __attribute__((aligned (64)));
212
213
214 static 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
221 static 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
228 static inline void vppjni_unlock (vppjni_main_t * jm)
229 {
230   jm->tag = 0;
231   CLIB_MEMORY_BARRIER();
232   jm->lock = 0;
233 }
234
235 static inline f64 vppjni_time_now (vppjni_main_t *jm)
236 {
237   return clib_time_now (&jm->clib_time);
238 }
239
240 static 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
249 typedef __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
256 void 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)                                  \
261 do {                                            \
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)                               \
270 do {                                            \
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__ */