vxlan: multiarch optimization of vxlan
[vpp.git] / src / plugins / l2e / l2e.c
1 /*
2  * l2e.c : Extract L3 packets from the L2 input and feed
3  *                   them into the L3 path.
4  *
5  * Copyright (c) 2013 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 #include <plugins/l2e/l2e.h>
20 #include <vnet/l2/l2_input.h>
21 #include <vnet/l2/feat_bitmap.h>
22 #include <vnet/ip/ip.h>
23
24 l2_emulation_main_t l2_emulation_main;
25
26 /**
27  * A zero'd out struct we can use in the vec_validate
28  */
29 static const l2_emulation_t ezero = { };
30
31 __clib_export void
32 l2_emulation_enable (u32 sw_if_index)
33 {
34   l2_emulation_main_t *em = &l2_emulation_main;
35   vec_validate_init_empty (em->l2_emulations, sw_if_index, ezero);
36
37   l2_emulation_t *l23e = &em->l2_emulations[sw_if_index];
38
39   l23e->enabled = 1;
40
41   /*
42    * L3 enable the interface - using IP unnumbered from the control
43    * plane may not be possible since there may be no BVI interface
44    * to which to unnumber
45    */
46   ip4_sw_interface_enable_disable (sw_if_index, 1);
47   ip6_sw_interface_enable_disable (sw_if_index, 1);
48
49   l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_L2_EMULATION, 1);
50 }
51
52
53 __clib_export void
54 l2_emulation_disable (u32 sw_if_index)
55 {
56   l2_emulation_main_t *em = &l2_emulation_main;
57   if (vec_len (em->l2_emulations) >= sw_if_index)
58     {
59       l2_emulation_t *l23e = &em->l2_emulations[sw_if_index];
60       clib_memset (l23e, 0, sizeof (*l23e));
61
62       l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_L2_EMULATION, 0);
63       ip4_sw_interface_enable_disable (sw_if_index, 0);
64       ip6_sw_interface_enable_disable (sw_if_index, 0);
65     }
66 }
67
68 static clib_error_t *
69 l2_emulation_interface_add_del (vnet_main_t * vnm,
70                                 u32 sw_if_index, u32 is_add)
71 {
72   l2_emulation_main_t *em = &l2_emulation_main;
73   if (is_add)
74     {
75       vec_validate_init_empty (em->l2_emulations, sw_if_index, ezero);
76     }
77
78   return (NULL);
79 }
80
81 VNET_SW_INTERFACE_ADD_DEL_FUNCTION (l2_emulation_interface_add_del);
82
83 static clib_error_t *
84 l2_emulation_cli (vlib_main_t * vm,
85                   unformat_input_t * input, vlib_cli_command_t * cmd)
86 {
87   vnet_main_t *vnm = vnet_get_main ();
88   u32 sw_if_index = ~0;
89   u8 enable = 1;
90
91   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
92     {
93       if (unformat (input, "%U", unformat_vnet_sw_interface,
94                     vnm, &sw_if_index))
95         ;
96       else if (unformat (input, "enable"))
97         enable = 1;
98       else if (unformat (input, "disable"))
99         enable = 0;
100       else
101         break;
102     }
103
104   if (~0 == sw_if_index)
105     return clib_error_return (0, "interface must be specified");
106
107   if (enable)
108     l2_emulation_enable (sw_if_index);
109   else
110     l2_emulation_disable (sw_if_index);
111
112   return (NULL);
113 }
114
115 /*?
116  * Configure l2 emulation.
117  *  When the interface is in L2 mode, configure the extraction of L3
118  *  packets out of the L2 path and into the L3 path.
119  *
120  * @cliexpar
121  * @cliexstart{set interface l2 input l2-emulation <interface-name> [disable]}
122  * @cliexend
123  ?*/
124 /* *INDENT-OFF* */
125 VLIB_CLI_COMMAND (l2_emulation_cli_node, static) = {
126   .path = "set interface l2 l2-emulation",
127   .short_help =
128   "set interface l2 l2-emulation <interface-name> [disable|enable]\n",
129   .function = l2_emulation_cli,
130 };
131 /* *INDENT-ON* */
132
133 static clib_error_t *
134 l2_emulation_show (vlib_main_t * vm,
135                    unformat_input_t * input, vlib_cli_command_t * cmd)
136 {
137   l2_emulation_main_t *em = &l2_emulation_main;
138   vnet_main_t *vnm = vnet_get_main ();
139   l2_emulation_t *l23e;
140   u32 sw_if_index;
141
142   vec_foreach_index (sw_if_index, em->l2_emulations)
143   {
144     l23e = &em->l2_emulations[sw_if_index];
145     if (l23e->enabled)
146       {
147         vlib_cli_output (vm, "%U\n",
148                          format_vnet_sw_if_index_name, vnm, sw_if_index);
149       }
150   }
151   return (NULL);
152 }
153
154 /*?
155  * Show l2 emulation.
156  *  When the interface is in L2 mode, configure the extraction of L3
157  *  packets out of the L2 path and into the L3 path.
158  *
159  * @cliexpar
160  * @cliexstart{show interface l2 l2-emulation}
161  * @cliexend
162  ?*/
163 /* *INDENT-OFF* */
164 VLIB_CLI_COMMAND (l2_emulation_show_node, static) = {
165   .path = "show interface l2 l2-emulation",
166   .short_help = "show interface l2 l2-emulation\n",
167   .function = l2_emulation_show,
168 };
169 /* *INDENT-ON* */
170
171 static clib_error_t *
172 l2_emulation_init (vlib_main_t * vm)
173 {
174   l2_emulation_main_t *em = &l2_emulation_main;
175   vlib_node_t *node;
176
177   node = vlib_get_node_by_name (vm, (u8 *) "l2-emulation");
178   em->l2_emulation_node_index = node->index;
179
180   /* Initialize the feature next-node indexes */
181   feat_bitmap_init_next_nodes (vm,
182                                em->l2_emulation_node_index,
183                                L2INPUT_N_FEAT,
184                                l2input_get_feat_names (),
185                                em->l2_input_feat_next);
186
187   return 0;
188 }
189
190 VLIB_INIT_FUNCTION (l2_emulation_init);
191
192 /*
193  * fd.io coding-style-patch-verification: ON
194  *
195  * Local Variables:
196  * eval: (c-set-style "gnu")
197  * End:
198  */