FD.io VPP  v17.01.1-3-gc6833f8
Vector Packet Processing
l2sess.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 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 /*
16  *------------------------------------------------------------------
17  * l2sess.c - simple MAC-swap API / debug CLI handling
18  *------------------------------------------------------------------
19  */
20 
21 #include <vnet/vnet.h>
22 #include <vnet/plugin/plugin.h>
23 #include <acl/l2sess.h>
24 
25 #include <vlibapi/api.h>
26 #include <vlibmemory/api.h>
27 #include <vlibsocket/api.h>
28 #include <vppinfra/timing_wheel.h>
29 
30 #include <vnet/l2/l2_output.h>
31 #include <vnet/l2/l2_input.h>
32 
33 void
35  int from_early_init)
36 {
38  vnet_plugin_handoff_t * h = hh;
39  memset (sm, 0, sizeof (*sm));
40 
41  sm->vlib_main = vm;
42  sm->vnet_main = h->vnet_main;
44 }
45 
46 void
48 {
49 #define _(node_name, node_var, is_out, is_ip6, is_track) \
50  if (is_out) \
51  feat_bitmap_init_next_nodes(vm, node_var.index, L2OUTPUT_N_FEAT, \
52  l2output_get_feat_names (), \
53  sm->node_var ## _feat_next_node_index); \
54  else \
55  feat_bitmap_init_next_nodes(vm, node_var.index, L2INPUT_N_FEAT, \
56  l2input_get_feat_names (), \
57  sm->node_var ## _feat_next_node_index);
58 
60 #undef _
61 }
62 
63 void
65  u8 * prev_node_name, int add_output_nodes)
66 {
67  vlib_node_t *n;
68  n = vlib_get_node_by_name (vm, prev_node_name);
69 #define _(node_name, node_var, is_out, is_ip6, is_track) \
70  if (is_out == add_output_nodes) { \
71  u32 idx = vlib_node_add_next_with_slot(vm, n->index, node_var.index, ~0); \
72  if (is_track) { \
73  sm->next_slot_track_node_by_is_ip6_is_out[is_ip6][is_out] = idx; \
74  } \
75  }
77 #undef _
78 }
79 
80 void
82 {
83  vlib_main_t *vm = vlib_get_main ();
85 
87 
88  l2sess_add_our_next_nodes (vm, sm, (u8 *) "l2-input-classify", 0);
89  l2sess_add_our_next_nodes (vm, sm, (u8 *) "l2-output-classify", 1);
90 
91 }
92 
93 static char *
94 get_l4_proto_str (int is_ip6, uint8_t l4_proto)
95 {
96  switch (l4_proto)
97  {
98  case 6:
99  return "tcp";
100  case 17:
101  return "udp";
102  case 1:
103  return "icmp";
104  case 58:
105  return "icmp6";
106  default:
107  return "<?l4-unknown?>";
108  }
109 }
110 
111 static clib_error_t *
113  unformat_input_t * input, vlib_cli_command_t * cmd)
114 {
115  l2sess_main_t *sm = &l2sess_main;
116  clib_time_t *ct = &vm->clib_time;
117  l2s_session_t *s;
118  u64 now = clib_cpu_time_now ();
119 
120  vlib_cli_output (vm, "Timing wheel info: \n%U", format_timing_wheel,
121  &sm->timing_wheel, 255);
122 
123  pool_foreach (s, sm->sessions, (
124  {
125  f64 ctime =
126  (now -
127  s->create_time) * ct->seconds_per_clock;
128  f64 atime0 =
129  (now -
130  s->side[0].active_time) *
131  ct->seconds_per_clock;
132  f64 atime1 =
133  (now -
134  s->side[1].active_time) *
135  ct->seconds_per_clock;
136 /*
137  f64 ctime = (s->create_time - vm->cpu_time_main_loop_start) * ct->seconds_per_clock;
138  f64 atime0 = (s->side[0].active_time - vm->cpu_time_main_loop_start) * ct->seconds_per_clock;
139  f64 atime1 = (s->side[1].active_time - vm->cpu_time_main_loop_start) * ct->seconds_per_clock;
140 */
141  u8 * out0 =
142  format (0,
143  "%5d: create time: %U pkts/bytes/active time: [ %ld %ld %U : %ld %ld %U ]\n",
144  (s - sm->sessions),
145  format_time_interval, "h:m:s:u",
146  ctime, s->side[0].n_packets,
147  s->side[0].n_bytes,
148  format_time_interval, "h:m:s:u",
149  atime0, s->side[1].n_packets,
150  s->side[1].n_bytes,
151  format_time_interval, "h:m:s:u",
152  atime1); u8 * out1 = 0;
153  if (s->is_ip6)
154  {
155  out1 =
156  format (0, "%s %U :%u <-> %U :%u",
157  get_l4_proto_str (s->is_ip6,
158  s->l4_proto),
159  format_ip6_address,
160  &s->side[0].addr.ip6,
161  s->side[0].port,
162  format_ip6_address,
163  &s->side[1].addr.ip6,
164  s->side[1].port);}
165  else
166  {
167  out1 =
168  format (0, "%s %U :%u <-> %U :%u",
169  get_l4_proto_str (s->is_ip6,
170  s->l4_proto),
171  format_ip4_address,
172  &s->side[0].addr.ip4,
173  s->side[0].port,
174  format_ip4_address,
175  &s->side[1].addr.ip4,
176  s->side[1].port);}
177  vlib_cli_output (vm, "%s %s", out0,
178  out1); vec_free (out0);
179  vec_free (out1);}
180  ));
181  return 0;
182 }
183 
184 static clib_error_t *
186  unformat_input_t * input,
187  vlib_cli_command_t * cmd)
188 {
189  l2sess_main_t *sm = &l2sess_main;
190 
191  vlib_cli_output (vm, "Timing wheel info: \n%U", format_timing_wheel,
192  &sm->timing_wheel, 255);
193  vlib_cli_output (vm, "session pool len: %d, pool elts: %d",
194  pool_len (sm->sessions), pool_elts (sm->sessions));
195  vlib_cli_output (vm,
196  "attempted to delete sessions which were already free: %d",
198  return 0;
199 }
200 
201 
202 /* *INDENT-OFF* */
203 VLIB_CLI_COMMAND (l2sess_show_command, static) = {
204  .path = "show l2sess",
205  .short_help = "show l2sess",
206  .function = l2sess_show_command_fn,
207 };
208 
209 VLIB_CLI_COMMAND (l2sess_show_count_command, static) = {
210  .path = "show l2sess count",
211  .short_help = "show l2sess count",
212  .function = l2sess_show_count_command_fn,
213 };
214 /* *INDENT-OFF* */
215 
216 static inline u64
218 {
219  return (u64)(((f64)sec)/ct->seconds_per_clock);
220 }
221 
223 {
224  l2sess_main_t * sm = &l2sess_main;
225  clib_error_t * error = 0;
226  u64 cpu_time_now = clib_cpu_time_now();
227 
228 
229  clib_time_t *ct = &vm->clib_time;
233 
234  /* The min sched time of 10e-1 causes erroneous behavior... */
235  sm->timing_wheel.min_sched_time = 10e-2;
236  sm->timing_wheel.max_sched_time = 3600.0*48.0;
237  timing_wheel_init (&sm->timing_wheel, cpu_time_now, vm->clib_time.clocks_per_second);
240  /* Pre-allocate expired nodes. */
242 
245 
246  return error;
247 }
248 
250 
251 
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
void timing_wheel_init(timing_wheel_t *w, u64 current_cpu_time, f64 cpu_clocks_per_second)
Definition: timing_wheel.c:21
static clib_error_t * l2sess_show_count_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2sess.c:185
f64 clocks_per_second
Definition: time.h:53
static u64 clib_cpu_time_now(void)
Definition: time.h:73
clib_time_t clib_time
Definition: main.h:62
#define vec_alloc(V, N)
Allocate space for N more elements (no header, unspecified alignment)
Definition: vec.h:239
#define pool_len(p)
Number of elements in pool vector.
Definition: pool.h:121
ethernet_main_t * ethernet_main
Definition: plugin.h:27
static char * get_l4_proto_str(int is_ip6, uint8_t l4_proto)
Definition: l2sess.c:94
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
void l2sess_init_next_features(vlib_main_t *vm, l2sess_main_t *sm)
Definition: l2sess.c:47
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
format_function_t format_timing_wheel
Definition: timing_wheel.h:142
unsigned long u64
Definition: types.h:89
ethernet_main_t * ethernet_main
Definition: l2sess.h:134
timing_wheel_t timing_wheel
Definition: l2sess.h:126
l2s_session_t * sessions
Definition: l2sess.h:118
f64 seconds_per_clock
Definition: time.h:57
#define foreach_l2sess_node
Definition: l2sess.h:32
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:576
static clib_error_t * l2sess_init(vlib_main_t *vm)
Definition: l2sess.c:222
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
vlib_main_t * vlib_main
Definition: l2sess.h:132
foreach_l2sess_node l2_output_next_nodes_st output_next_nodes
Definition: l2sess.h:101
static u64 time_sec_to_clock(clib_time_t *ct, f64 sec)
Definition: l2sess.c:217
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
u64 timer_wheel_next_expiring_time
Definition: l2sess.h:128
u64 timer_wheel_tick
Definition: l2sess.h:129
u32 * data_from_advancing_timing_wheel
Definition: l2sess.h:127
l2sess_main_t l2sess_main
Definition: l2sess.h:140
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
#define UDP_SESSION_IDLE_TIMEOUT_SEC
Definition: l2sess.h:82
#define TCP_SESSION_IDLE_TIMEOUT_SEC
Definition: l2sess.h:83
double f64
Definition: types.h:142
static clib_error_t * l2sess_show_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: l2sess.c:112
unsigned char u8
Definition: types.h:56
void l2sess_setup_nodes(void)
Definition: l2sess.c:81
vnet_main_t * vnet_main
Definition: plugin.h:26
u64 udp_session_idle_timeout
Definition: l2sess.h:123
u64 counter_attempted_delete_free_session
Definition: l2sess.h:137
void l2sess_add_our_next_nodes(vlib_main_t *vm, l2sess_main_t *sm, u8 *prev_node_name, int add_output_nodes)
Definition: l2sess.c:64
u64 tcp_session_transient_timeout
Definition: l2sess.h:121
struct _unformat_input_t unformat_input_t
void l2sess_vlib_plugin_register(vlib_main_t *vm, void *hh, int from_early_init)
Definition: l2sess.c:34
static void l2output_init_output_node_vec(u32 **output_node_index_vec)
Definition: l2_output.h:168
u64 tcp_session_idle_timeout
Definition: l2sess.h:122
#define TCP_SESSION_TRANSIENT_TIMEOUT_SEC
Definition: l2sess.h:84
vnet_main_t * vnet_main
Definition: l2sess.h:133
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109