FD.io VPP  v17.10-9-gd594711
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 #include <vnet/l2/l2_input.h>
20 #include <vnet/l2/l2_output.h>
21 
22 #include <vnet/span/span.h>
23 
24 typedef enum
25 {
27  SPAN_RX = 1,
28  SPAN_TX = 2,
30 } span_state_t;
31 
33 span_dst_set (span_mirror_t * sm, u32 dst_sw_if_index, int enable)
34 {
35  if (dst_sw_if_index == ~0)
36  {
37  ASSERT (enable == 0);
39  }
40  else
41  sm->mirror_ports =
42  clib_bitmap_set (sm->mirror_ports, dst_sw_if_index, enable);
43 
46  return last;
47 }
48 
49 int
51  u32 src_sw_if_index, u32 dst_sw_if_index, u8 state,
52  span_feat_t sf)
53 {
54  span_main_t *sm = &span_main;
55 
56  if (state > SPAN_BOTH)
57  return VNET_API_ERROR_UNIMPLEMENTED;
58 
59  if ((src_sw_if_index == ~0) || (dst_sw_if_index == ~0 && state > 0)
60  || (src_sw_if_index == dst_sw_if_index))
61  return VNET_API_ERROR_INVALID_INTERFACE;
62 
63  vec_validate_aligned (sm->interfaces, src_sw_if_index,
65 
66  span_interface_t *si = vec_elt_at_index (sm->interfaces, src_sw_if_index);
67 
68  int rx = ! !(state & SPAN_RX);
69  int tx = ! !(state & SPAN_TX);
70 
71  span_mirror_t *rxm = &si->mirror_rxtx[sf][VLIB_RX];
72  span_mirror_t *txm = &si->mirror_rxtx[sf][VLIB_TX];
73 
74  u32 last_rx_ports_count = span_dst_set (rxm, dst_sw_if_index, rx);
75  u32 last_tx_ports_count = span_dst_set (txm, dst_sw_if_index, tx);
76 
77  int enable_rx = last_rx_ports_count == 0 && rxm->num_mirror_ports == 1;
78  int disable_rx = last_rx_ports_count > 0 && rxm->num_mirror_ports == 0;
79  int enable_tx = last_tx_ports_count == 0 && txm->num_mirror_ports == 1;
80  int disable_tx = last_tx_ports_count > 0 && txm->num_mirror_ports == 0;
81 
82  switch (sf)
83  {
84  case SPAN_FEAT_DEVICE:
85  if (enable_rx || disable_rx)
86  vnet_feature_enable_disable ("device-input", "span-input",
87  src_sw_if_index, rx, 0, 0);
88  if (enable_tx || disable_tx)
89  vnet_feature_enable_disable ("interface-output", "span-output",
90  src_sw_if_index, tx, 0, 0);
91  break;
92  case SPAN_FEAT_L2:
93  if (enable_rx || disable_rx)
94  l2input_intf_bitmap_enable (src_sw_if_index, L2INPUT_FEAT_SPAN, rx);
95  if (enable_tx || disable_tx)
96  l2output_intf_bitmap_enable (src_sw_if_index, L2OUTPUT_FEAT_SPAN, tx);
97  break;
98  default:
99  return VNET_API_ERROR_UNIMPLEMENTED;
100  }
101 
102  if (dst_sw_if_index != ~0 && dst_sw_if_index > sm->max_sw_if_index)
103  sm->max_sw_if_index = dst_sw_if_index;
104 
105  return 0;
106 }
107 
108 static uword
109 unformat_span_state (unformat_input_t * input, va_list * args)
110 {
111  span_state_t *state = va_arg (*args, span_state_t *);
112  if (unformat (input, "disable"))
113  *state = SPAN_DISABLE;
114  else if (unformat (input, "rx"))
115  *state = SPAN_RX;
116  else if (unformat (input, "tx"))
117  *state = SPAN_TX;
118  else if (unformat (input, "both"))
119  *state = SPAN_BOTH;
120  else
121  return 0;
122  return 1;
123 }
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  u32 src_sw_if_index = ~0;
132  u32 dst_sw_if_index = ~0;
135  int state_set = 0;
136 
138  {
139  if (unformat (input, "%U", unformat_vnet_sw_interface,
140  sm->vnet_main, &src_sw_if_index))
141  ;
142  else if (unformat (input, "destination %U", unformat_vnet_sw_interface,
143  sm->vnet_main, &dst_sw_if_index))
144  ;
145  else if (unformat (input, "%U", unformat_span_state, &state))
146  {
147  if (state_set)
148  return clib_error_return (0, "Multiple mirror states in input");
149  state_set = 1;
150  }
151  else if (unformat (input, "l2"))
152  sf = SPAN_FEAT_L2;
153  else
154  return clib_error_return (0, "Invalid input");
155  }
156 
157  int rv =
158  span_add_delete_entry (vm, src_sw_if_index, dst_sw_if_index, state, sf);
159  if (rv == VNET_API_ERROR_INVALID_INTERFACE)
160  return clib_error_return (0, "Invalid interface");
161  return 0;
162 }
163 
164 /* *INDENT-OFF* */
165 VLIB_CLI_COMMAND (set_interface_span_command, static) = {
166  .path = "set interface span",
167  .short_help = "set interface span <if-name> [l2] {disable | destination <if-name> [both|rx|tx]}",
168  .function = set_interface_span_command_fn,
169 };
170 /* *INDENT-ON* */
171 
172 static clib_error_t *
174  unformat_input_t * input,
175  vlib_cli_command_t * cmd)
176 {
177  span_main_t *sm = &span_main;
178  span_interface_t *si;
179  vnet_main_t *vnm = &vnet_main;
180  u8 header = 1;
181  static const char *states[] = {
182  [SPAN_DISABLE] = "none",
183  [SPAN_RX] = "rx",
184  [SPAN_TX] = "tx",
185  [SPAN_BOTH] = "both"
186  };
187  u8 *s = 0;
188 
189  /* *INDENT-OFF* */
190  vec_foreach (si, sm->interfaces)
191  {
194 
197 
198  if (drxm->num_mirror_ports || dtxm->num_mirror_ports ||
199  lrxm->num_mirror_ports || ltxm->num_mirror_ports)
200  {
201  u32 i;
204  clib_bitmap_t *b = clib_bitmap_dup_or (d, l);
205  if (header)
206  {
207  vlib_cli_output (vm, "%-20s %-20s %6s %6s", "Source", "Destination",
208  "Device", "L2");
209  header = 0;
210  }
211  s = format (s, "%U", format_vnet_sw_if_index_name, vnm,
212  si - sm->interfaces);
213  clib_bitmap_foreach (i, b, (
214  {
215  int device = (clib_bitmap_get (drxm->mirror_ports, i) +
216  clib_bitmap_get (dtxm->mirror_ports, i) * 2);
217  int l2 = (clib_bitmap_get (lrxm->mirror_ports, i) +
218  clib_bitmap_get (ltxm->mirror_ports, i) * 2);
219 
220  vlib_cli_output (vm, "%-20v %-20U (%6s) (%6s)", s,
222  states[device], states[l2]);
223  vec_reset_length (s);
224  }));
225  clib_bitmap_free (b);
226  clib_bitmap_free (l);
227  clib_bitmap_free (d);
228  }
229  }
230  /* *INDENT-ON* */
231  vec_free (s);
232  return 0;
233 }
234 
235 /* *INDENT-OFF* */
236 VLIB_CLI_COMMAND (show_interfaces_span_command, static) = {
237  .path = "show interface span",
238  .short_help = "Shows SPAN mirror table",
240 };
241 /* *INDENT-ON* */
242 
243 /*
244  * fd.io coding-style-patch-verification: ON
245  *
246  * Local Variables:
247  * eval: (c-set-style "gnu")
248  * End:
249  */
Definition: span.c:29
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
span_mirror_t mirror_rxtx[SPAN_FEAT_N][VLIB_N_RX_TX]
Definition: span.h:38
u32 num_mirror_ports
Definition: span.h:33
static heap_elt_t * last(heap_header_t *h)
Definition: heap.c:53
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
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:443
span_state_t
Definition: span.c:24
format_function_t format_vnet_sw_if_index_name
#define clib_bitmap_zero(v)
Clear a bitmap.
Definition: bitmap.h:102
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
clib_bitmap_t * mirror_ports
Definition: span.h:32
#define static_always_inline
Definition: clib.h:85
#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
Definition: span.c:27
Definition: span.c:28
void l2output_intf_bitmap_enable(u32 sw_if_index, u32 feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_output.c:686
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
static uword unformat_span_state(unformat_input_t *input, va_list *args)
Definition: span.c:109
span_interface_t * interfaces
Definition: span.h:48
vnet_main_t * vnet_main
Definition: span.h:55
struct _unformat_input_t unformat_input_t
vnet_main_t vnet_main
Definition: misc.c:43
span_main_t span_main
Definition: span.h:58
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
int span_add_delete_entry(vlib_main_t *vm, u32 src_sw_if_index, u32 dst_sw_if_index, u8 state, span_feat_t sf)
Definition: span.c:50
vlib_main_t * vm
Definition: buffer.c:283
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
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:126
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
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static_always_inline u32 span_dst_set(span_mirror_t *sm, u32 dst_sw_if_index, int enable)
Definition: span.c:33
vhost_vring_state_t state
Definition: vhost-user.h:82
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
u64 uword
Definition: types.h:112
u32 l2input_intf_bitmap_enable(u32 sw_if_index, u32 feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_input.c:534
static uword clib_bitmap_count_set_bits(uword *ai)
Return the number of set bits in a bitmap.
Definition: bitmap.h:441
Definition: defs.h:47
unsigned char u8
Definition: types.h:56
span_feat_t
Definition: span.h:23
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:173
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:51
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
Definition: defs.h:46
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:229
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169