FD.io VPP  v17.07.01-10-g3be13f0
Vector Packet Processing
span.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 #include <vlib/vlib.h>
17 #include <vppinfra/error.h>
18 #include <vnet/feature/feature.h>
19 
20 #include <vnet/span/span.h>
21 
22 int
24  u32 src_sw_if_index, u32 dst_sw_if_index, u8 state)
25 {
26  span_main_t *sm = &span_main;
27  span_interface_t *si;
28  u32 new_num_rx_mirror_ports, new_num_tx_mirror_ports;
29 
30  if (state > 3)
31  return VNET_API_ERROR_UNIMPLEMENTED;
32 
33  if ((src_sw_if_index == ~0) || (dst_sw_if_index == ~0 && state > 0)
34  || (src_sw_if_index == dst_sw_if_index))
35  return VNET_API_ERROR_INVALID_INTERFACE;
36 
37  vnet_sw_interface_t *sw_if;
38 
39  sw_if = vnet_get_sw_interface (vnet_get_main (), src_sw_if_index);
40  if (sw_if->type == VNET_SW_INTERFACE_TYPE_SUB)
41  return VNET_API_ERROR_UNIMPLEMENTED;
42 
43  vec_validate_aligned (sm->interfaces, src_sw_if_index,
45  si = vec_elt_at_index (sm->interfaces, src_sw_if_index);
46 
47  si->rx_mirror_ports = clib_bitmap_set (si->rx_mirror_ports, dst_sw_if_index,
48  (state & 1) != 0);
49  si->tx_mirror_ports = clib_bitmap_set (si->tx_mirror_ports, dst_sw_if_index,
50  (state & 2) != 0);
51 
52  new_num_rx_mirror_ports = clib_bitmap_count_set_bits (si->rx_mirror_ports);
53  new_num_tx_mirror_ports = clib_bitmap_count_set_bits (si->tx_mirror_ports);
54 
55  if (new_num_rx_mirror_ports == 1 && si->num_rx_mirror_ports == 0)
56  vnet_feature_enable_disable ("device-input", "span-input",
57  src_sw_if_index, 1, 0, 0);
58 
59  if (new_num_rx_mirror_ports == 0 && si->num_rx_mirror_ports == 1)
60  vnet_feature_enable_disable ("device-input", "span-input",
61  src_sw_if_index, 0, 0, 0);
62 
63  if (new_num_rx_mirror_ports == 1 && si->num_rx_mirror_ports == 0)
64  vnet_feature_enable_disable ("interface-output", "span-output",
65  src_sw_if_index, 1, 0, 0);
66 
67  if (new_num_rx_mirror_ports == 0 && si->num_rx_mirror_ports == 1)
68  vnet_feature_enable_disable ("interface-output", "span-output",
69  src_sw_if_index, 0, 0, 0);
70 
71  si->num_rx_mirror_ports = new_num_rx_mirror_ports;
72  si->num_tx_mirror_ports = new_num_tx_mirror_ports;
73 
74  if (dst_sw_if_index > sm->max_sw_if_index)
75  sm->max_sw_if_index = dst_sw_if_index;
76 
77  return 0;
78 }
79 
80 static clib_error_t *
82  unformat_input_t * input,
83  vlib_cli_command_t * cmd)
84 {
85  span_main_t *sm = &span_main;
86  u32 src_sw_if_index = ~0;
87  u32 dst_sw_if_index = ~0;
88  u8 state = 3;
89 
91  {
92  if (unformat (input, "%U", unformat_vnet_sw_interface,
93  sm->vnet_main, &src_sw_if_index))
94  ;
95  else if (unformat (input, "destination %U", unformat_vnet_sw_interface,
96  sm->vnet_main, &dst_sw_if_index))
97  ;
98  else if (unformat (input, "disable"))
99  state = 0;
100  else if (unformat (input, "rx"))
101  state = 1;
102  else if (unformat (input, "tx"))
103  state = 2;
104  else if (unformat (input, "both"))
105  state = 3;
106  else
107  break;
108  }
109 
110  int rv =
111  span_add_delete_entry (vm, src_sw_if_index, dst_sw_if_index, state);
112  if (rv == VNET_API_ERROR_INVALID_INTERFACE)
113  return clib_error_return (0, "Invalid interface");
114  return 0;
115 }
116 
117 /* *INDENT-OFF* */
118 VLIB_CLI_COMMAND (set_interface_span_command, static) = {
119  .path = "set interface span",
120  .short_help = "set interface span <if-name> [disable | destination <if-name> [both|rx|tx]]",
121  .function = set_interface_span_command_fn,
122 };
123 /* *INDENT-ON* */
124 
125 static clib_error_t *
127  unformat_input_t * input,
128  vlib_cli_command_t * cmd)
129 {
130  span_main_t *sm = &span_main;
131  span_interface_t *si;
132  vnet_main_t *vnm = &vnet_main;
133  u8 header = 1;
134  char *states[] = { "none", "rx", "tx", "both" };
135  u8 *s = 0;
136 
137  /* *INDENT-OFF* */
138  vec_foreach (si, sm->interfaces)
140  {
141  clib_bitmap_t *b;
142  u32 i;
144  if (header)
145  {
146  vlib_cli_output (vm, "%-40s %s", "Source interface",
147  "Mirror interface (direction)");
148  header = 0;
149  }
150  s = format (s, "%U", format_vnet_sw_if_index_name, vnm,
151  si - sm->interfaces);
152  clib_bitmap_foreach (i, b, (
153  {
154  int state;
155  state = (clib_bitmap_get (si->rx_mirror_ports, i) +
156  clib_bitmap_get (si->tx_mirror_ports, i) * 2);
157 
158  vlib_cli_output (vm, "%-40v %U (%s)", s,
160  states[state]);
161  vec_reset_length (s);
162  }));
163  clib_bitmap_free (b);
164  }
165  /* *INDENT-ON* */
166  vec_free (s);
167  return 0;
168 }
169 
170 /* *INDENT-OFF* */
171 VLIB_CLI_COMMAND (show_interfaces_span_command, static) = {
172  .path = "show interface span",
173  .short_help = "Shows SPAN mirror table",
175 };
176 /* *INDENT-ON* */
177 
178 static clib_error_t *
180 {
181  span_main_t *sm = &span_main;
182 
183  sm->vlib_main = vm;
184  sm->vnet_main = vnet_get_main ();
185 
186  return 0;
187 }
188 
190 
191 /*
192  * fd.io coding-style-patch-verification: ON
193  *
194  * Local Variables:
195  * eval: (c-set-style "gnu")
196  * End:
197  */
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vlib_main_t * vlib_main
Definition: span.h:39
int span_add_delete_entry(vlib_main_t *vm, u32 src_sw_if_index, u32 dst_sw_if_index, u8 state)
Definition: span.c:23
static uword * clib_bitmap_set(uword *ai, uword i, uword value)
Sets the ith bit of a bitmap to new_value Removes trailing zeros from the bitmap. ...
Definition: bitmap.h:167
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unformat_function_t unformat_vnet_sw_interface
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:447
format_function_t format_vnet_sw_if_index_name
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
#define clib_error_return(e, args...)
Definition: error.h:99
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
span_interface_t * interfaces
Definition: span.h:33
vnet_main_t * vnet_main
Definition: span.h:40
struct _unformat_input_t unformat_input_t
vnet_main_t vnet_main
Definition: misc.c:43
span_main_t span_main
Definition: span.h:43
clib_bitmap_t * tx_mirror_ports
Definition: span.h:25
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
static clib_error_t * set_interface_span_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: span.c:81
static uword * clib_bitmap_dup_or(uword *ai, uword *bi)
Logical operator across two bitmaps which duplicates the first bitmap.
static uword clib_bitmap_get(uword *ai, uword i)
Gets the ith bit value from a bitmap.
Definition: bitmap.h:197
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
unsigned int u32
Definition: types.h:88
static clib_error_t * span_init(vlib_main_t *vm)
Definition: span.c:179
vhost_vring_state_t state
Definition: vhost-user.h:81
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
u32 num_rx_mirror_ports
Definition: span.h:26
static uword clib_bitmap_count_set_bits(uword *ai)
Return the number of set bits in a bitmap.
Definition: bitmap.h:441
unsigned char u8
Definition: types.h:56
u32 num_tx_mirror_ports
Definition: span.h:27
clib_bitmap_t * rx_mirror_ports
Definition: span.h:24
vnet_sw_interface_type_t type
Definition: interface.h:555
static clib_error_t * show_interfaces_span_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: span.c:126
uword clib_bitmap_t
Definition: bitmap.h:50
#define vec_foreach(var, vec)
Vector iterator.
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
u32 max_sw_if_index
Definition: span.h:36
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:225
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169