diff options
author | Jim Gibson <gibson@cisco.com> | 2017-02-20 11:53:54 -0500 |
---|---|---|
committer | Jim Gibson <gibson@cisco.com> | 2017-02-20 12:21:12 -0500 |
commit | dfd7ce27fea04c1a76844e21286c2b1d6653e153 (patch) | |
tree | 0025f965ddb68599ea824b9d9edf61b7647dd4ec /cicn-plugin/cicn/cicn_infra.h | |
parent | 9b30fc10fb1cbebe651e5a107e8ca5b24de54675 (diff) |
Initial Commit: VPP cicn VPP plugin
Change-Id: If1b965f0a4b7cfacda8f6caf6925072a9007ffb4
Signed-off-by: Jim Gibson <gibson@cisco.com>
Diffstat (limited to 'cicn-plugin/cicn/cicn_infra.h')
-rw-r--r-- | cicn-plugin/cicn/cicn_infra.h | 312 |
1 files changed, 312 insertions, 0 deletions
diff --git a/cicn-plugin/cicn/cicn_infra.h b/cicn-plugin/cicn/cicn_infra.h new file mode 100644 index 00000000..3013e1eb --- /dev/null +++ b/cicn-plugin/cicn/cicn_infra.h @@ -0,0 +1,312 @@ +/* + * Copyright (c) 2017 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. + */ +/* + * plugin infrastructure: global data structure, common definitions, + * statistics, etc + */ +#ifndef _CICN_INFRA_H_ +#define _CICN_INFRA_H_ 1 + +#if !CICN_VPP_PLUGIN +#error "cicn-internal file included externally" +#endif + +typedef int (*test_cicn_api_handler_fn) (test_cicn_api_op_t * + test_cicn_api_op); + +// cicn plugin global state: see also +// - icnfwd_runtime_s for per-worker state +// - fib and pits +typedef struct cicn_main_s +{ + /* Binary API message ID base */ + u16 msg_id_base; + + /* Have we been enabled */ + u16 is_enabled; + + /* Convenience */ + vlib_main_t *vlib_main; + vnet_main_t *vnet_main; + ethernet_main_t *ethernet_main; + + /* Global FIB instance */ + cicn_fib_t fib; + + /* Info about vpp worker threads, used in our packet distribution node */ + u32 shard_count; // 1 in single-threaded or 1 worker mode: see worker_count + u32 worker_count; // 0 in single-threaded case: see shard_count + u32 worker_first_index; + + /* Node index for forwarder node in dpdk worker handoff context */ + u32 fwd_next_node; + + /* Global PIT lifetime info */ + uint64_t pit_lifetime_dflt_ms; + uint64_t pit_lifetime_min_ms; + uint64_t pit_lifetime_max_ms; + + /* Global ICN Hello Protocol Polling Interval */ + f64 cicn_hello_interval; + + /* The name of the ICN Hello Protocol Interests */ + cicn_hello_name_t hello_name; + + /* Is Hello Protocol polling interval set from cli/api? */ + u32 cicn_hello_interval_cfgd; + + /* Next node id for Hello Interests */ + u32 cicn_hello_next_node_id; + + /* Array of ICN Adjacencies indexed by faceid */ + cicn_hello_adj_t cicn_hello_adjs[CICN_PARAM_FACES_MAX]; + + /* Array of ICN Hello data by faceid */ + cicn_hello_data cicn_hello_data_array[CICN_PARAM_FACES_MAX]; + + /* Number of active adjacencies */ + u32 n_active_hello_adjs; + + uword *cicn_rc_strings; // to print string forms of return codes + + /* Event subscribers' info */ + i32 n_face_event_subscribers; + vl_api_cicn_api_face_events_subscribe_t + face_event_subscribers[CICN_PARAM_API_EVENT_SUBSCRIBERS_MAX]; + + /* Have we been enabled for packet-generation? */ + u32 pgen_enabled; + + /* pgen client side */ + /* Source and destination info */ + u32 pgen_clt_src_addr; + int pgen_clt_src_port; + u32 pgen_clt_dest_addr; + int pgen_clt_dest_port; + + /* pgen server side */ + /* Have we enabled the packet generator server? */ + u32 pgen_svr_enabled; + + /* Arbitrary content */ + u32 pgen_svr_buffer_idx; + + test_cicn_api_handler_fn test_cicn_api_handler; +} cicn_main_t; + +extern cicn_main_t cicn_main; + +static inline char * +cicn_sstrncpy (char *dst, const char *src, size_t n) +{ + char *res = strncpy (dst, src, n); + dst[n - 1] = '\000'; + return (res); +} + +/* Forwarder's name data structure */ +typedef struct cicn_infra_fwdr_name_s +{ + uint64_t fn_match_pfx_hash; // hash of fname's relevant pfx for match + int fn_reply_payload_flen; // total bytes in reply payload +#define CICN_FWDR_NAME_BUFSIZE 200 + uint8_t fn_reply_payload[CICN_FWDR_NAME_BUFSIZE]; // wire-fmt reply payload + cicn_prefix_hashinf_t fn_hashinf; // hash of fname components + char fn_str[CICN_FWDR_NAME_BUFSIZE]; // fname ascii version for output +} cicn_infra_fwdr_name_t; + +/* Global name of the forwarder */ +extern cicn_infra_fwdr_name_t cicn_infra_fwdr_name; + +extern int cicn_infra_fwdr_initialized; + +/* + * Generation numbers for coordination between config changes and running + * worker threads. Certain configuration changes (deletes, especially) + * cause the master config generation to increment. Each worker checks the + * master value and updates its own dedicated value as it begins each + * frame of work. We hope this allows us to safely integrate configuration + * changes without more costly synchronization. + */ + +/* Each value is actually a stand-alone cache line in size, so that + * the worker threads don't have to be entangled trying to make high-rate + * updates to shared cache lines. + */ +typedef struct cicn_infra_shard_s +{ + volatile uint64_t cfg_generation; + uint64_t _extra[7]; + cicn_face_stats_t face_stats[CICN_PARAM_FACES_MAX]; +} cicn_infra_shard_t; + +/* Global generation value, updated for (some? all?) config changes */ +extern cicn_infra_shard_t cicn_infra_gshard; + +#define CICN_INFRA_CFG_GEN_INCR() (cicn_infra_gshard.cfg_generation++) + +/* Fixed array for worker threads, to be indexed by worker index */ +#define CICN_INFRA_WORKERS_MAX 24 +extern cicn_infra_shard_t cicn_infra_shards[CICN_INFRA_WORKERS_MAX]; + +/* Per shard limits */ +uint32_t cicn_infra_shard_pit_size; +uint32_t cicn_infra_shard_cs_size; + +/* cicn-owned return code for cases where unix rc are insufficient */ +#define foreach_cicn_rc \ +_(OK, 0, "ok") \ +_(FACE_UNKNOWN, 1, "face unknown") \ +_(FIB_PFX_COMP_LIMIT, 2, "fib prefix too man components") \ +_(FIB_PFX_SIZE_LIMIT, 3, "fib prefix too long") \ +_(FIB_NHOP_LIMIT, 4, "fib next hop limit exceeded") + +typedef enum +{ +#define _(a,b,c) CICN_RC_##a = b, + foreach_cicn_rc +#undef _ +} cicn_rc_e; + +struct cicn_rd_s +{ + cicn_rc_e rd_cicn_rc; + int rd_ux_rc; +}; + +static inline void +cicn_rd_set (cicn_rd_t * cicn_rd, cicn_rc_e cicn_rc, int ux_rc) +{ + cicn_rd->rd_cicn_rc = cicn_rc; + cicn_rd->rd_ux_rc = ux_rc; +} + +/* + * Printable error representation + */ +const char *cicn_rc_str (cicn_rc_e crc); + +const char *cicn_rd_str (cicn_rd_t * cicn_rd); + +/* + * wrapped timer sequence package (increment, comparison) + */ + +/* + * wrappable counter math (assumed uint16_t): return sum of addends + */ +static inline uint16_t +cicn_infra_seq16_sum (uint16_t addend1, uint16_t addend2) +{ + return (addend1 + addend2); +} + +/* + * for comparing wrapping numbers, return lt,eq,gt 0 for a lt,eq,gt b + */ +static inline int +cicn_infra_seq16_cmp (uint16_t a, uint16_t b) +{ + return ((int16_t) (a - b)); +} + +/* + * below are wrappers for lt, le, gt, ge seq16 comparators + */ +static inline int +cicn_infra_seq16_lt (uint16_t a, uint16_t b) +{ + return (cicn_infra_seq16_cmp (a, b) < 0); +} + +static inline int +cicn_infra_seq16_le (uint16_t a, uint16_t b) +{ + return (cicn_infra_seq16_cmp (a, b) <= 0); +} + +static inline int +cicn_infra_seq16_gt (uint16_t a, uint16_t b) +{ + return (cicn_infra_seq16_cmp (a, b) > 0); +} + +static inline int +cicn_infra_seq16_ge (uint16_t a, uint16_t b) +{ + return (cicn_infra_seq16_cmp (a, b) >= 0); +} + +/* Definitions and Forward refs for the time counters we're trying out. + * Counters are maintained by the background process. + */ +#define SEC_MS 1000 +#define CICN_INFRA_FAST_TIMER_SECS 1 +#define CICN_INFRA_FAST_TIMER_MSECS (CICN_INFRA_FAST_TIMER_SECS * SEC_MS) +#define CICN_INFRA_SLOW_TIMER_SECS 60 +#define CICN_INFRA_SLOW_TIMER_MSECS (CICN_INFRA_SLOW_TIMER_SECS * SEC_MS) + +extern uint16_t cicn_infra_fast_timer; /* Counts at 1 second intervals */ +extern uint16_t cicn_infra_slow_timer; /* Counts at 1 minute intervals */ + +/* + * Utilities to convert lifetime into expiry time based on + * compressed clock, suitable for the opportunistic hashtable + * entry timeout processing. + */ + +// convert time in msec to time in clicks +static inline uint16_t +cicn_infra_ms2clicks (uint64_t time_ms, uint64_t ms_per_click) +{ + f64 time_clicks = + ((f64) (time_ms + ms_per_click - 1)) / ((f64) ms_per_click); + return ((uint16_t) time_clicks); +} + +static inline uint16_t +cicn_infra_get_fast_exp_time (uint64_t lifetime_ms) +{ + uint16_t lifetime_clicks = + cicn_infra_ms2clicks (lifetime_ms, CICN_INFRA_FAST_TIMER_MSECS); + return (cicn_infra_seq16_sum (cicn_infra_fast_timer, lifetime_clicks)); +} + +static inline uint16_t +cicn_infra_get_slow_exp_time (uint64_t lifetime_ms) +{ + uint16_t lifetime_clicks = + cicn_infra_ms2clicks (lifetime_ms, CICN_INFRA_SLOW_TIMER_MSECS); + return (cicn_infra_seq16_sum (cicn_infra_slow_timer, lifetime_clicks)); +} + +int +cicn_infra_plugin_enable_disable (int enable_disable, + int fib_max_size, + int pit_max_size, + f64 pit_dflt_lifetime_sec_req, + f64 pit_min_lifetime_sec_req, + f64 pit_max_lifetime_sec_req, + int cs_max_size); + +/* First versions of the ICN nodes: the forwarder node, the work-distributor + * node and the packet-generator client and server nodes + */ +extern vlib_node_registration_t icnfwd_node; +extern vlib_node_registration_t icndist_node; +extern vlib_node_registration_t icn_pg_node; +extern vlib_node_registration_t icn_pg_server_node; + +#endif // _CICN_INFRA_H_ |