2 * policy_encap.c: mpls-o-e policy encap
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 #include <vlib/vlib.h>
19 #include <vnet/pg/pg.h>
20 #include <vnet/mpls/mpls.h>
21 #include <vnet/classify/vnet_classify.h>
26 } mpls_policy_encap_trace_t;
28 u8 * format_mpls_policy_encap_trace (u8 * s, va_list * args)
30 CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
31 CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
32 mpls_policy_encap_trace_t * t = va_arg (*args, mpls_policy_encap_trace_t *);
34 s = format (s, "MPLS-POLICY-ENCAP: next-index %d encap-index %d",
35 t->next_index, t->encap_index);
40 vlib_node_registration_t mpls_policy_encap_node;
42 #define foreach_mpls_policy_encap_next \
46 #define _(s,n) MPLS_POLICY_ENCAP_NEXT_##s,
47 foreach_mpls_policy_encap_next
49 MPLS_POLICY_ENCAP_N_NEXT,
50 } mpls_policy_encap_next_t;
52 #define foreach_mpls_policy_error \
53 _(PKTS_ENCAP, "mpls policy tunnel packets encapsulated")
56 #define _(n,s) MPLS_POLICY_ENCAP_ERROR_##n,
57 foreach_mpls_policy_error
58 MPLS_POLICY_ENCAP_N_ERROR,
60 } mpls_policy_encap_error_t;
62 static char * mpls_policy_encap_error_strings[] =
65 foreach_mpls_policy_error
70 mpls_policy_encap (vlib_main_t * vm,
71 vlib_node_runtime_t * node,
72 vlib_frame_t * from_frame)
74 u32 n_left_from, next_index, * from, * to_next;
75 mpls_main_t * mm = &mpls_main;
77 from = vlib_frame_vector_args (from_frame);
78 n_left_from = from_frame->n_vectors;
80 next_index = node->cached_next_index;
82 while (n_left_from > 0)
86 vlib_get_next_frame (vm, node, next_index,
87 to_next, n_left_to_next);
89 while (n_left_from > 0 && n_left_to_next > 0)
105 b0 = vlib_get_buffer (vm, bi0);
107 encap_index0 = vnet_buffer(b0)->l2_classify.opaque_index;
109 e0 = pool_elt_at_index (mm->encaps, encap_index0);
111 vlib_buffer_advance (b0, -(word)vec_len(e0->rewrite));
112 h0 = vlib_buffer_get_current (b0);
113 clib_memcpy (h0, e0->rewrite, vec_len(e0->rewrite));
115 next0 = e0->output_next_index;
117 if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
119 mpls_policy_encap_trace_t *tr =
120 vlib_add_trace (vm, node, b0, sizeof (*tr));
121 tr->next_index = next0;
122 tr->encap_index = encap_index0;
124 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
125 to_next, n_left_to_next,
128 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
130 vlib_node_increment_counter (vm, mpls_policy_encap_node.index,
131 MPLS_POLICY_ENCAP_ERROR_PKTS_ENCAP,
132 from_frame->n_vectors);
133 return from_frame->n_vectors;
136 VLIB_REGISTER_NODE (mpls_policy_encap_node) = {
137 .function = mpls_policy_encap,
138 .name = "mpls-policy-encap",
139 /* Takes a vector of packets. */
140 .vector_size = sizeof (u32),
142 .runtime_data_bytes = 0,
144 .n_errors = MPLS_POLICY_ENCAP_N_ERROR,
145 .error_strings = mpls_policy_encap_error_strings,
147 .format_trace = format_mpls_policy_encap_trace,
149 .n_next_nodes = MPLS_POLICY_ENCAP_N_NEXT,
151 #define _(s,n) [MPLS_POLICY_ENCAP_NEXT_##s] = n,
152 foreach_mpls_policy_encap_next
157 VLIB_NODE_FUNCTION_MULTIARCH (mpls_policy_encap_node, mpls_policy_encap)
159 static clib_error_t *
160 mpls_policy_encap_init (vlib_main_t * vm)
162 mpls_main_t * mm = &mpls_main;
163 clib_error_t * error;
165 if ((error = vlib_call_init_function (vm, mpls_init)))
168 mm->ip4_classify_mpls_policy_encap_next_index =
169 vlib_node_add_next (mm->vlib_main,
170 ip4_classify_node.index,
171 mpls_policy_encap_node.index);
173 mm->ip6_classify_mpls_policy_encap_next_index =
174 vlib_node_add_next (mm->vlib_main,
175 ip6_classify_node.index,
176 mpls_policy_encap_node.index);
181 VLIB_INIT_FUNCTION (mpls_policy_encap_init);