FD.io VPP  v16.06
Vector Packet Processing
policy_encap.c
Go to the documentation of this file.
1 /*
2  * policy_encap.c: mpls-o-e policy encap
3  *
4  * Copyright (c) 2012-2014 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 #include <vlib/vlib.h>
19 #include <vnet/pg/pg.h>
20 #include <vnet/mpls-gre/mpls.h>
21 
22 typedef struct {
26 
27 u8 * format_mpls_policy_encap_trace (u8 * s, va_list * args)
28 {
29  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
30  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
32 
33  s = format (s, "MPLS-POLICY-ENCAP: next-index %d encap-index %d",
34  t->next_index, t->encap_index);
35 
36  return s;
37 }
38 
40 
41 #define foreach_mpls_policy_encap_next \
42 _(DROP, "error-drop")
43 
44 typedef enum {
45 #define _(s,n) MPLS_POLICY_ENCAP_NEXT_##s,
47 #undef _
50 
51 #define foreach_mpls_policy_error \
52 _(PKTS_ENCAP, "mpls policy tunnel packets encapsulated")
53 
54 typedef enum {
55 #define _(n,s) MPLS_POLICY_ENCAP_ERROR_##n,
58 #undef _
60 
62  {
63 #define _(n,s) s,
65 #undef _
66 };
67 
68 static uword
70  vlib_node_runtime_t * node,
71  vlib_frame_t * from_frame)
72 {
73  u32 n_left_from, next_index, * from, * to_next;
74  mpls_main_t * mm = &mpls_main;
75 
76  from = vlib_frame_vector_args (from_frame);
77  n_left_from = from_frame->n_vectors;
78 
79  next_index = node->cached_next_index;
80 
81  while (n_left_from > 0)
82  {
83  u32 n_left_to_next;
84 
85  vlib_get_next_frame (vm, node, next_index,
86  to_next, n_left_to_next);
87 
88  while (n_left_from > 0 && n_left_to_next > 0)
89  {
90  u32 bi0;
91  vlib_buffer_t * b0;
92  u8 * h0;
93  u32 encap_index0;
94  u32 next0;
95  mpls_encap_t * e0;
96 
97  bi0 = from[0];
98  to_next[0] = bi0;
99  from += 1;
100  to_next += 1;
101  n_left_from -= 1;
102  n_left_to_next -= 1;
103 
104  b0 = vlib_get_buffer (vm, bi0);
105 
106  encap_index0 = vnet_buffer(b0)->l2_classify.opaque_index;
107 
108  e0 = pool_elt_at_index (mm->encaps, encap_index0);
109 
111  h0 = vlib_buffer_get_current (b0);
112  clib_memcpy (h0, e0->rewrite, vec_len(e0->rewrite));
113 
114  next0 = e0->output_next_index;
115 
117  {
119  vlib_add_trace (vm, node, b0, sizeof (*tr));
120  tr->next_index = next0;
121  tr->encap_index = encap_index0;
122  }
123  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
124  to_next, n_left_to_next,
125  bi0, next0);
126  }
127  vlib_put_next_frame (vm, node, next_index, n_left_to_next);
128  }
130  MPLS_POLICY_ENCAP_ERROR_PKTS_ENCAP,
131  from_frame->n_vectors);
132  return from_frame->n_vectors;
133 }
134 
136  .function = mpls_policy_encap,
137  .name = "mpls-policy-encap",
138  /* Takes a vector of packets. */
139  .vector_size = sizeof (u32),
140 
141  .runtime_data_bytes = 0,
142 
143  .n_errors = MPLS_POLICY_ENCAP_N_ERROR,
144  .error_strings = mpls_policy_encap_error_strings,
145 
146  .format_trace = format_mpls_policy_encap_trace,
147 
148  .n_next_nodes = MPLS_POLICY_ENCAP_N_NEXT,
149  .next_nodes = {
150 #define _(s,n) [MPLS_POLICY_ENCAP_NEXT_##s] = n,
152 #undef _
153  },
154 };
155 
156 static clib_error_t *
158 {
159  mpls_main_t * mm = &mpls_main;
160  clib_error_t * error;
161  u32 ip6_next_index;
162 
163  if ((error = vlib_call_init_function (vm, mpls_init)))
164  return error;
165 
168  ip4_classify_node.index,
169  mpls_policy_encap_node.index);
170 
171  /*
172  * Must add the same arc to ip6_classify so the
173  * next-index vectors are congruent
174  */
175  ip6_next_index =
177  ip6_classify_node.index,
178  mpls_policy_encap_node.index);
179 
180  if (ip6_next_index != mm->ip_classify_mpls_policy_encap_next_index)
181  return clib_error_return
182  (0, "ip4/ip6 classifier next vector botch: %d vs %d",
183  ip6_next_index, mm->ip_classify_mpls_policy_encap_next_index);
184 
185  return 0;
186 }
187 
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Definition: main.c:459
#define CLIB_UNUSED(x)
Definition: clib.h:79
struct _vlib_node_registration vlib_node_registration_t
static clib_error_t * mpls_policy_encap_init(vlib_main_t *vm)
Definition: policy_encap.c:157
u32 ip_classify_mpls_policy_encap_next_index
Definition: mpls.h:99
u8 * format_mpls_policy_encap_trace(u8 *s, va_list *args)
Definition: policy_encap.c:27
always_inline void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
Definition: buffer.h:184
vlib_node_registration_t ip4_classify_node
(constructor) VLIB_REGISTER_NODE (ip4_classify_node)
Definition: ip_classify.c:37
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:109
#define vlib_call_init_function(vm, x)
Definition: init.h:159
always_inline void * vlib_frame_vector_args(vlib_frame_t *f)
Definition: node_funcs.h:202
#define foreach_mpls_policy_encap_next
Definition: policy_encap.c:41
#define pool_elt_at_index(p, i)
Definition: pool.h:346
mpls_policy_encap_error_t
Definition: policy_encap.c:54
#define PREDICT_FALSE(x)
Definition: clib.h:97
always_inline void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
Definition: node_funcs.h:970
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Definition: buffer_node.h:83
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Definition: node_funcs.h:265
u32 output_next_index
Definition: mpls.h:73
u8 * rewrite
Definition: mpls.h:72
u16 n_vectors
Definition: node.h:307
mpls_main_t mpls_main
Definition: mpls.c:21
#define clib_memcpy(a, b, c)
Definition: string.h:63
mpls_policy_encap_next_t
Definition: policy_encap.c:44
static uword mpls_policy_encap(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
Definition: policy_encap.c:69
u16 cached_next_index
Definition: node.h:422
unsigned int u32
Definition: types.h:88
#define vnet_buffer(b)
Definition: buffer.h:300
u8 * format(u8 *s, char *fmt,...)
Definition: format.c:405
always_inline uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:919
#define VLIB_BUFFER_IS_TRACED
Definition: buffer.h:91
#define foreach_mpls_policy_error
Definition: policy_encap.c:51
u64 uword
Definition: types.h:112
static clib_error_t * mpls_init(vlib_main_t *vm)
Definition: mpls.c:770
i64 word
Definition: types.h:111
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
always_inline void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
Definition: buffer.h:197
unsigned char u8
Definition: types.h:56
always_inline void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
Definition: trace_funcs.h:55
vlib_main_t * vlib_main
Definition: mpls.h:102
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:140
static char * mpls_policy_encap_error_strings[]
Definition: policy_encap.c:61
#define clib_error_return(e, args...)
Definition: error.h:112
vlib_node_registration_t ip6_classify_node
(constructor) VLIB_REGISTER_NODE (ip6_classify_node)
Definition: ip_classify.c:38
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
Definition: buffer.h:84
always_inline vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
Definition: buffer_funcs.h:69
vlib_node_registration_t mpls_policy_encap_node
(constructor) VLIB_REGISTER_NODE (mpls_policy_encap_node)
Definition: policy_encap.c:39
mpls_encap_t * encaps
Definition: mpls.h:91