/* * Copyright (c) 2015 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef __included_vppjni_h__ #define __included_vppjni_h__ #include #include #include #include #include #include #include typedef struct { u8 * name; u32 value; } name_sort_t; typedef struct { u8 valid; // used in a vector of sw_interface_details_t u8 interface_name[64]; u32 sw_if_index; u32 sup_sw_if_index; u32 l2_address_length; u8 l2_address[8]; u8 admin_up_down; u8 link_up_down; u8 link_duplex; u8 link_speed; u32 sub_id; u8 sub_dot1ad; u8 sub_number_of_tags; u16 sub_outer_vlan_id; u16 sub_inner_vlan_id; u8 sub_exact_match; u8 sub_default; u8 sub_outer_vlan_id_any; u8 sub_inner_vlan_id_any; u32 vtr_op; u32 vtr_push_dot1q; u32 vtr_tag1; u32 vtr_tag2; } sw_interface_details_t; typedef struct { u8 * interface_name; u32 sw_if_index; /* * Subinterface ID. A number 0-N to uniquely identify * this subinterface under the super interface */ u32 sub_id; /* 0 = dot1q, 1=dot1ad */ u8 sub_dot1ad; /* Number of tags 0-2 */ u8 sub_number_of_tags; u16 sub_outer_vlan_id; u16 sub_inner_vlan_id; u8 sub_exact_match; u8 sub_default; u8 sub_outer_vlan_id_any; u8 sub_inner_vlan_id_any; /* vlan tag rewrite */ u32 vtr_op; u32 vtr_push_dot1q; u32 vtr_tag1; u32 vtr_tag2; } sw_interface_subif_t; typedef struct { u64 ip4; u64 ip6; u64 unicast; u64 multicast; u64 broadcast; u64 discard; u64 fifo_full; u64 error; u64 unknown_proto; u64 miss; } packet_counters_t; typedef struct { u64 octets; packet_counters_t pkts; } if_counters_t; typedef struct { u8 valid; u32 sw_if_index; if_counters_t rx; if_counters_t tx; } sw_interface_stats_t; typedef struct { /* Context IDs */ volatile u32 context_id_sent; volatile u32 context_id_received; /* Spinlock */ volatile u32 lock; u32 tag; /* To recycle pseudo-synchronous message code from vpe_api_test... */ volatile u32 result_ready; volatile i32 retval; volatile u8 *shmem_result; /* thread cleanup */ pthread_key_t cleanup_rx_thread_key; /* attachment of rx thread to java thread */ JNIEnv *jenv; JavaVM *jvm; jclass jcls; jmethodID jmtdIfDetails; // interfaceDetails method uword *callback_hash; // map context_id => jobject uword *ping_hash; // map ping context_id => msg type called /* Timestamp */ clib_time_t clib_time; /* connected indication */ u8 is_connected; /* context -> non-trivial reply hash */ uword * reply_hash; u32 saved_reply_count; /* interface name map */ uword * sw_if_index_by_interface_name; /* interface counters */ sw_interface_stats_t * sw_if_stats_by_sw_if_index; /* interface table */ sw_interface_details_t * sw_if_table; /* interface indices of responses to one sw_if_dump request */ u8 collect_indices; u32 * sw_if_dump_if_indices; /* program name, build_dir, git_version */ u8 program_name[32]; u8 build_directory[256]; u8 git_branch[32]; u8 build_date[32]; /* subinterface table */ sw_interface_subif_t * sw_if_subif_table; /* main heap */ u8 * heap; /* convenience */ unix_shared_memory_queue_t * vl_input_queue; api_main_t * api_main; u32 my_client_index; vjbd_main_t vjbd_main; } vppjni_main_t; vppjni_main_t vppjni_main __attribute__((aligned (64))); static inline u32 vppjni_get_context_id (vppjni_main_t * jm) { u32 my_context_id; my_context_id = __sync_add_and_fetch (&jm->context_id_sent, 1); return my_context_id; } static inline void vppjni_lock (vppjni_main_t * jm, u32 tag) { while (__sync_lock_test_and_set (&jm->lock, 1)) ; jm->tag = tag; } static inline void vppjni_unlock (vppjni_main_t * jm) { jm->tag = 0; CLIB_MEMORY_BARRIER(); jm->lock = 0; } static inline f64 vppjni_time_now (vppjni_main_t *jm) { return clib_time_now (&jm->clib_time); } static inline int vppjni_sanity_check (vppjni_main_t * jm) { if (!jm->is_connected) return VNET_API_ERROR_NOT_CONNECTED; return 0; } #define __PACKED(x) x __attribute__((packed)) typedef __PACKED(struct _vl_api_generic_reply { u16 _vl_msg_id; u32 context; i32 retval; u8 data[0]; }) vl_api_generic_reply_t; void vl_api_generic_reply_handler (vl_api_generic_reply_t *mp); /* M: construct, but don't yet send a message */ #define M(T,t) \ do { \ jm->result_ready = 0; \ mp = vl_msg_api_alloc(sizeof(*mp)); \ memset (mp, 0, sizeof (*mp)); \ mp->_vl_msg_id = ntohs (VL_API_##T); \ mp->client_index = jm->my_client_index; \ } while(0); #define M2(T,t,n) \ do { \ jm->result_ready = 0; \ mp = vl_msg_api_alloc(sizeof(*mp)+(n)); \ memset (mp, 0, sizeof (*mp)); \ mp->_vl_msg_id = ntohs (VL_API_##T); \ mp->client_index = jm->my_client_index; \ } while(0); /* S: send a message */ #define S (vl_msg_api_send_shmem (jm->vl_input_queue, (u8 *)&mp)) /* W: wait for results, with timeout */ #define W \ do { \ timeout = vppjni_time_now (jm) + 1.0; \ \ while (vppjni_time_now (jm) < timeout) { \ if (jm->result_ready == 1) { \ return (jm->retval); \ } \ } \ return -99; \ } while(0); /* WNR: wait for results, with timeout (without returning) */ #define WNR \ do { \ timeout = vppjni_time_now (jm) + 1.0; \ \ rv = -99; \ while (vppjni_time_now (jm) < timeout) { \ if (jm->result_ready == 1) { \ rv = (jm->retval); \ break; \ } \ } \ } while(0); #endif /* __included_vppjni_h__ */