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-gre/mpls.h>
25 } mpls_policy_encap_trace_t;
27 u8 * format_mpls_policy_encap_trace (u8 * s, va_list * args)
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 *);
31 mpls_policy_encap_trace_t * t = va_arg (*args, mpls_policy_encap_trace_t *);
33 s = format (s, "MPLS-POLICY-ENCAP: next-index %d encap-index %d",
34 t->next_index, t->encap_index);
39 vlib_node_registration_t mpls_policy_encap_node;
41 #define foreach_mpls_policy_encap_next \
45 #define _(s,n) MPLS_POLICY_ENCAP_NEXT_##s,
46 foreach_mpls_policy_encap_next
48 MPLS_POLICY_ENCAP_N_NEXT,
49 } mpls_policy_encap_next_t;
51 #define foreach_mpls_policy_error \
52 _(PKTS_ENCAP, "mpls policy tunnel packets encapsulated")
55 #define _(n,s) MPLS_POLICY_ENCAP_ERROR_##n,
56 foreach_mpls_policy_error
57 MPLS_POLICY_ENCAP_N_ERROR,
59 } mpls_policy_encap_error_t;
61 static char * mpls_policy_encap_error_strings[] =
64 foreach_mpls_policy_error
69 mpls_policy_encap (vlib_main_t * vm,
70 vlib_node_runtime_t * node,
71 vlib_frame_t * from_frame)
73 u32 n_left_from, next_index, * from, * to_next;
74 mpls_main_t * mm = &mpls_main;
76 from = vlib_frame_vector_args (from_frame);
77 n_left_from = from_frame->n_vectors;
79 next_index = node->cached_next_index;
81 while (n_left_from > 0)
85 vlib_get_next_frame (vm, node, next_index,
86 to_next, n_left_to_next);
88 while (n_left_from > 0 && n_left_to_next > 0)
104 b0 = vlib_get_buffer (vm, bi0);
106 encap_index0 = vnet_buffer(b0)->l2_classify.opaque_index;
108 e0 = pool_elt_at_index (mm->encaps, encap_index0);
110 vlib_buffer_advance (b0, -(word)vec_len(e0->rewrite));
111 h0 = vlib_buffer_get_current (b0);
112 memcpy (h0, e0->rewrite, vec_len(e0->rewrite));
114 next0 = e0->output_next_index;
116 if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
118 mpls_policy_encap_trace_t *tr =
119 vlib_add_trace (vm, node, b0, sizeof (*tr));
120 tr->next_index = next0;
121 tr->encap_index = encap_index0;
123 vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
124 to_next, n_left_to_next,
127 vlib_put_next_frame (vm, node, next_index, n_left_to_next);
129 vlib_node_increment_counter (vm, mpls_policy_encap_node.index,
130 MPLS_POLICY_ENCAP_ERROR_PKTS_ENCAP,
131 from_frame->n_vectors);
132 return from_frame->n_vectors;
135 VLIB_REGISTER_NODE (mpls_policy_encap_node) = {
136 .function = mpls_policy_encap,
137 .name = "mpls-policy-encap",
138 /* Takes a vector of packets. */
139 .vector_size = sizeof (u32),
141 .runtime_data_bytes = 0,
143 .n_errors = MPLS_POLICY_ENCAP_N_ERROR,
144 .error_strings = mpls_policy_encap_error_strings,
146 .format_trace = format_mpls_policy_encap_trace,
148 .n_next_nodes = MPLS_POLICY_ENCAP_N_NEXT,
150 #define _(s,n) [MPLS_POLICY_ENCAP_NEXT_##s] = n,
151 foreach_mpls_policy_encap_next
156 static clib_error_t *
157 mpls_policy_encap_init (vlib_main_t * vm)
159 mpls_main_t * mm = &mpls_main;
160 clib_error_t * error;
163 if ((error = vlib_call_init_function (vm, mpls_init)))
166 mm->ip_classify_mpls_policy_encap_next_index =
167 vlib_node_add_next (mm->vlib_main,
168 ip4_classify_node.index,
169 mpls_policy_encap_node.index);
172 * Must add the same arc to ip6_classify so the
173 * next-index vectors are congruent
176 vlib_node_add_next (mm->vlib_main,
177 ip6_classify_node.index,
178 mpls_policy_encap_node.index);
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);
188 VLIB_INIT_FUNCTION (mpls_policy_encap_init);