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 : /**
16 : * @brief
17 : * The data-path object representing performing a lookup in the IPv6
18 : * link local table
19 : */
20 :
21 : #include <vnet/dpo/ip6_ll_dpo.h>
22 : #include <vnet/ip/ip6_ll_table.h>
23 :
24 : /**
25 : * @brief the IP6 link-local DPO is global
26 : */
27 : static dpo_id_t ip6_ll_dpo = {
28 : .dpoi_type = DPO_IP6_LL,
29 : .dpoi_proto = DPO_PROTO_IP6,
30 : .dpoi_index = 0,
31 : };
32 :
33 : const dpo_id_t *
34 2741 : ip6_ll_dpo_get (void)
35 : {
36 2741 : return (&ip6_ll_dpo);
37 : }
38 :
39 : static void
40 13705 : ip6_ll_dpo_lock (dpo_id_t * dpo)
41 : {
42 : /*
43 : * not maintaining a lock count on the ip6_ll, they are const global and
44 : * never die.
45 : */
46 13705 : }
47 :
48 : static void
49 11995 : ip6_ll_dpo_unlock (dpo_id_t * dpo)
50 : {
51 11995 : }
52 :
53 : static u8 *
54 202 : format_ip6_ll_dpo (u8 * s, va_list * ap)
55 : {
56 202 : CLIB_UNUSED (index_t index) = va_arg (*ap, index_t);
57 202 : CLIB_UNUSED (u32 indent) = va_arg (*ap, u32);
58 :
59 202 : return (format (s, "ip6-link-local"));
60 : }
61 :
62 : const static dpo_vft_t ip6_ll_vft = {
63 : .dv_lock = ip6_ll_dpo_lock,
64 : .dv_unlock = ip6_ll_dpo_unlock,
65 : .dv_format = format_ip6_ll_dpo,
66 : };
67 :
68 : /**
69 : * @brief The per-protocol VLIB graph nodes that are assigned to a ip6_ll
70 : * object.
71 : *
72 : * this means that these graph nodes are ones from which a ip6_ll is the
73 : * parent object in the DPO-graph.
74 : */
75 : const static char *const ip6_null_nodes[] = {
76 : "ip6-link-local",
77 : NULL,
78 : };
79 :
80 : const static char *const *const ip6_ll_nodes[DPO_PROTO_NUM] = {
81 : [DPO_PROTO_IP6] = ip6_null_nodes,
82 : };
83 :
84 : typedef struct ip6_ll_dpo_trace_t_
85 : {
86 : u32 fib_index;
87 : u32 sw_if_index;
88 : } ip6_ll_dpo_trace_t;
89 :
90 : /**
91 : * @brief Exit nodes from a IP6_LL
92 : */
93 : typedef enum ip6_ll_next_t_
94 : {
95 : IP6_LL_NEXT_DROP,
96 : IP6_LL_NEXT_LOOKUP,
97 : IP6_LL_NEXT_NUM,
98 : } ip6_ll_next_t;
99 :
100 : typedef enum ip6_ll_error_t_
101 : {
102 : IP6_LL_ERROR_NO_TABLE,
103 : } ip6_ll_error_t;
104 :
105 : always_inline uword
106 45 : ip6_ll_dpo_inline (vlib_main_t * vm,
107 : vlib_node_runtime_t * node, vlib_frame_t * frame)
108 : {
109 : u32 n_left_from, next_index, *from, *to_next;
110 :
111 45 : from = vlib_frame_vector_args (frame);
112 45 : n_left_from = frame->n_vectors;
113 45 : next_index = node->cached_next_index;
114 :
115 90 : while (n_left_from > 0)
116 : {
117 : u32 n_left_to_next;
118 :
119 45 : vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);
120 :
121 90 : while (n_left_from > 0 && n_left_to_next > 0)
122 : {
123 : u32 bi0, fib_index0, next0;
124 : vlib_buffer_t *p0;
125 :
126 45 : bi0 = from[0];
127 45 : to_next[0] = bi0;
128 45 : from += 1;
129 45 : to_next += 1;
130 45 : n_left_from -= 1;
131 45 : n_left_to_next -= 1;
132 45 : next0 = IP6_LL_NEXT_LOOKUP;
133 :
134 45 : p0 = vlib_get_buffer (vm, bi0);
135 :
136 : /* use the packet's RX interface to pick the link-local FIB */
137 : fib_index0 =
138 45 : ip6_ll_fib_get (vnet_buffer (p0)->sw_if_index[VLIB_RX]);
139 :
140 45 : if (~0 == fib_index0)
141 : {
142 0 : next0 = IP6_LL_NEXT_DROP;
143 0 : p0->error = node->errors[IP6_LL_ERROR_NO_TABLE];
144 0 : goto trace0;
145 : }
146 :
147 : /* write that fib index into the packet so it's used in the
148 : * lookup node next */
149 45 : vnet_buffer (p0)->sw_if_index[VLIB_TX] = fib_index0;
150 :
151 45 : trace0:
152 45 : if (PREDICT_FALSE (p0->flags & VLIB_BUFFER_IS_TRACED))
153 : {
154 45 : ip6_ll_dpo_trace_t *tr = vlib_add_trace (vm, node, p0,
155 : sizeof (*tr));
156 45 : tr->sw_if_index = vnet_buffer (p0)->sw_if_index[VLIB_RX];
157 45 : tr->fib_index = fib_index0;
158 : }
159 45 : vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next,
160 : n_left_to_next, bi0, next0);
161 : }
162 :
163 45 : vlib_put_next_frame (vm, node, next_index, n_left_to_next);
164 : }
165 :
166 45 : return frame->n_vectors;
167 : }
168 :
169 : static u8 *
170 28 : format_ip6_ll_dpo_trace (u8 * s, va_list * args)
171 : {
172 28 : CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
173 28 : CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
174 28 : ip6_ll_dpo_trace_t *t = va_arg (*args, ip6_ll_dpo_trace_t *);
175 :
176 28 : s = format (s, "sw_if_index:%d fib_index:%d", t->sw_if_index, t->fib_index);
177 28 : return s;
178 : }
179 :
180 : static uword
181 45 : ip6_ll_dpo_switch (vlib_main_t * vm,
182 : vlib_node_runtime_t * node, vlib_frame_t * frame)
183 : {
184 45 : return (ip6_ll_dpo_inline (vm, node, frame));
185 : }
186 :
187 : static char *ip6_ll_dpo_error_strings[] = {
188 : [IP6_LL_ERROR_NO_TABLE] = "Interface is not mapped to an IP6-LL table",
189 : };
190 :
191 : /**
192 : * @brief
193 : */
194 : /* *INDENT-OFF* */
195 178120 : VLIB_REGISTER_NODE (ip6_ll_dpo_node) =
196 : {
197 : .function = ip6_ll_dpo_switch,
198 : .name = "ip6-link-local",
199 : .vector_size = sizeof (u32),
200 : .format_trace = format_ip6_ll_dpo_trace,
201 : .n_errors = ARRAY_LEN (ip6_ll_dpo_error_strings),
202 : .error_strings = ip6_ll_dpo_error_strings,
203 : .n_next_nodes = IP6_LL_NEXT_NUM,
204 : .next_nodes = {
205 : [IP6_LL_NEXT_DROP] = "ip6-drop",
206 : [IP6_LL_NEXT_LOOKUP] = "ip6-lookup",
207 : },
208 : };
209 : /* *INDENT-ON* */
210 :
211 : void
212 559 : ip6_ll_dpo_module_init (void)
213 : {
214 559 : dpo_register (DPO_IP6_LL, &ip6_ll_vft, ip6_ll_nodes);
215 559 : }
216 :
217 : /*
218 : * fd.io coding-style-patch-verification: ON
219 : *
220 : * Local Variables:
221 : * eval: (c-set-style "gnu")
222 : * End:
223 : */
|