Line data Source code
1 : /*
2 : * Copyright (c) 2018 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 : #include <nat/dslite/dslite.h>
16 :
17 : typedef enum
18 : {
19 : DSLITE_CE_DECAP_NEXT_IP4_LOOKUP,
20 : DSLITE_IN2OUT_NEXT_IP6_ICMP,
21 : DSLITE_CE_DECAP_NEXT_DROP,
22 : DSLITE_CE_DECAP_N_NEXT,
23 : } dslite_ce_decap_next_t;
24 :
25 : static char *dslite_ce_decap_error_strings[] = {
26 : #define _(sym,string) string,
27 : foreach_dslite_error
28 : #undef _
29 : };
30 :
31 2302 : VLIB_NODE_FN (dslite_ce_decap_node) (vlib_main_t * vm,
32 : vlib_node_runtime_t * node,
33 : vlib_frame_t * frame)
34 : {
35 : u32 n_left_from, *from, *to_next;
36 : dslite_ce_decap_next_t next_index;
37 :
38 2 : from = vlib_frame_vector_args (frame);
39 2 : n_left_from = frame->n_vectors;
40 2 : next_index = node->cached_next_index;
41 :
42 4 : while (n_left_from > 0)
43 : {
44 : u32 n_left_to_next;
45 :
46 2 : vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
47 :
48 4 : while (n_left_from > 0 && n_left_to_next > 0)
49 : {
50 : u32 bi0;
51 : vlib_buffer_t *b0;
52 2 : u32 next0 = DSLITE_CE_DECAP_NEXT_IP4_LOOKUP;
53 2 : u8 error0 = DSLITE_ERROR_CE_DECAP;
54 : ip4_header_t *ip40;
55 : ip6_header_t *ip60;
56 : u32 proto0;
57 :
58 : /* speculatively enqueue b0 to the current next frame */
59 2 : bi0 = from[0];
60 2 : to_next[0] = bi0;
61 2 : from += 1;
62 2 : to_next += 1;
63 2 : n_left_from -= 1;
64 2 : n_left_to_next -= 1;
65 :
66 2 : b0 = vlib_get_buffer (vm, bi0);
67 2 : ip60 = vlib_buffer_get_current (b0);
68 :
69 2 : if (PREDICT_FALSE (ip60->protocol != IP_PROTOCOL_IP_IN_IP))
70 : {
71 1 : if (ip60->protocol == IP_PROTOCOL_ICMP6)
72 : {
73 1 : next0 = DSLITE_IN2OUT_NEXT_IP6_ICMP;
74 1 : goto trace0;
75 : }
76 0 : error0 = DSLITE_ERROR_BAD_IP6_PROTOCOL;
77 0 : next0 = DSLITE_CE_DECAP_NEXT_DROP;
78 0 : goto trace0;
79 : }
80 :
81 1 : ip40 = vlib_buffer_get_current (b0) + sizeof (ip6_header_t);
82 1 : proto0 = ip_proto_to_nat_proto (ip40->protocol);
83 :
84 1 : if (PREDICT_FALSE (proto0 == NAT_PROTOCOL_OTHER))
85 : {
86 0 : error0 = DSLITE_ERROR_UNSUPPORTED_PROTOCOL;
87 0 : next0 = DSLITE_CE_DECAP_NEXT_DROP;
88 0 : goto trace0;
89 : }
90 :
91 1 : ip40->tos =
92 1 : (clib_net_to_host_u32
93 1 : (ip60->ip_version_traffic_class_and_flow_label) & 0x0ff00000) >>
94 : 20;
95 1 : vlib_buffer_advance (b0, sizeof (ip6_header_t));
96 :
97 2 : trace0:
98 2 : if (PREDICT_FALSE ((node->flags & VLIB_NODE_FLAG_TRACE)
99 : && (b0->flags & VLIB_BUFFER_IS_TRACED)))
100 : {
101 2 : dslite_trace_t *t = vlib_add_trace (vm, node, b0, sizeof (*t));
102 2 : t->next_index = next0;
103 : }
104 :
105 2 : b0->error = node->errors[error0];
106 :
107 : /* verify speculative enqueue, maybe switch current next frame */
108 2 : vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
109 : n_left_to_next, bi0, next0);
110 : }
111 2 : vlib_put_next_frame (vm, node, next_index, n_left_to_next);
112 : }
113 :
114 2 : return frame->n_vectors;
115 : }
116 :
117 : /* *INDENT-OFF* */
118 148652 : VLIB_REGISTER_NODE (dslite_ce_decap_node) = {
119 : .name = "dslite-ce-decap",
120 : .vector_size = sizeof (u32),
121 : .format_trace = format_dslite_ce_trace,
122 : .type = VLIB_NODE_TYPE_INTERNAL,
123 : .n_errors = ARRAY_LEN (dslite_ce_decap_error_strings),
124 : .error_strings = dslite_ce_decap_error_strings,
125 : .n_next_nodes = DSLITE_CE_DECAP_N_NEXT,
126 : /* edit / add dispositions here */
127 : .next_nodes = {
128 : [DSLITE_CE_DECAP_NEXT_DROP] = "error-drop",
129 : [DSLITE_CE_DECAP_NEXT_IP4_LOOKUP] = "ip4-lookup",
130 : [DSLITE_IN2OUT_NEXT_IP6_ICMP] = "ip6-icmp-input",
131 : },
132 : };
133 : /* *INDENT-ON* */
134 :
135 : /*
136 : * fd.io coding-style-patch-verification: ON
137 : *
138 : * Local Variables:
139 : * eval: (c-set-style "gnu")
140 : * End:
141 : */
|