ip: Replace Sematics for Interface IP addresses
[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
23 l2_emulation_main_t l2_emulation_main;
24
25 /**
26  * A zero'd out struct we can use in the vec_validate
27  */
28 static const l2_emulation_t ezero = { };
29
30 void
31 l2_emulation_enable (u32 sw_if_index)
32 {
33   l2_emulation_main_t *em = &l2_emulation_main;
34   vec_validate_init_empty (em->l2_emulations, sw_if_index, ezero);
35
36   l2_emulation_t *l23e = &em->l2_emulations[sw_if_index];
37
38   l23e->enabled = 1;
39
40   /*
41    * L3 enable the interface - using IP unnumbered from the control
42    * plane may not be possible since there may be no BVI interface
43    * to which to unnumber
44    */
45   ip4_sw_interface_enable_disable (sw_if_index, 1);
46   ip6_sw_interface_enable_disable (sw_if_index, 1);
47
48   l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_L2_EMULATION, 1);
49 }
50
51
52 void
53 l2_emulation_disable (u32 sw_if_index)
54 {
55   l2_emulation_main_t *em = &l2_emulation_main;
56   if (vec_len (em->l2_emulations) >= sw_if_index)
57     {
58       l2_emulation_t *l23e = &em->l2_emulations[sw_if_index];
59       clib_memset (l23e, 0, sizeof (*l23e));
60
61       l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_L2_EMULATION, 0);
62       ip4_sw_interface_enable_disable (sw_if_index, 0);
63       ip6_sw_interface_enable_disable (sw_if_index, 0);
64     }
65 }
66
67 static clib_error_t *
68 l2_emulation_interface_add_del (vnet_main_t * vnm,
69                                 u32 sw_if_index, u32 is_add)
70 {
71   l2_emulation_main_t *em = &l2_emulation_main;
72   if (is_add)
73     {
74       vec_validate_init_empty (em->l2_emulations, sw_if_index, ezero);
75     }
76
77   return (NULL);
78 }
79
80 VNET_SW_INTERFACE_ADD_DEL_FUNCTION (l2_emulation_interface_add_del);
81
82 static clib_error_t *
83 l2_emulation_cli (vlib_main_t * vm,
84                   unformat_input_t * input, vlib_cli_command_t * cmd)
85 {
86   vnet_main_t *vnm = vnet_get_main ();
87   u32 sw_if_index = ~0;
88   u8 enable = 1;
89
90   while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
91     {
92       if (unformat (input, "%U", unformat_vnet_sw_interface,
93                     vnm, &sw_if_index))
94         ;
95       else if (unformat (input, "enable"))
96         enable = 1;
97       else if (unformat (input, "disable"))
98         enable = 0;
99       else
100         break;
101     }
102
103   if (~0 == sw_if_index)
104     return clib_error_return (0, "interface must be specified");
105
106   if (enable)
107     l2_emulation_enable (sw_if_index);
108   else
109     l2_emulation_disable (sw_if_index);
110
111   return (NULL);
112 }
113
114 /*?
115  * Configure l2 emulation.
116  *  When the interface is in L2 mode, configure the extraction of L3
117  *  packets out of the L2 path and into the L3 path.
118  *
119  * @cliexpar
120  * @cliexstart{set interface l2 input l2-emulation <interface-name> [disable]}
121  * @cliexend
122  ?*/
123 /* *INDENT-OFF* */
124 VLIB_CLI_COMMAND (l2_emulation_cli_node, static) = {
125   .path = "set interface l2 l2-emulation",
126   .short_help =
127   "set interface l2 l2-emulation <interface-name> [disable|enable]\n",
128   .function = l2_emulation_cli,
129 };
130 /* *INDENT-ON* */
131
132 static clib_error_t *
133 l2_emulation_show (vlib_main_t * vm,
134                    unformat_input_t * input, vlib_cli_command_t * cmd)
135 {
136   l2_emulation_main_t *em = &l2_emulation_main;
137   vnet_main_t *vnm = vnet_get_main ();
138   l2_emulation_t *l23e;
139   u32 sw_if_index;
140
141   vec_foreach_index (sw_if_index, em->l2_emulations)
142   {
143     l23e = &em->l2_emulations[sw_if_index];
144     if (l23e->enabled)
145       {
146         vlib_cli_output (vm, "%U\n",
147                          format_vnet_sw_if_index_name, vnm, sw_if_index);
148       }
149   }
150   return (NULL);
151 }
152
153 /*?
154  * Show l2 emulation.
155  *  When the interface is in L2 mode, configure the extraction of L3
156  *  packets out of the L2 path and into the L3 path.
157  *
158  * @cliexpar
159  * @cliexstart{show interface l2 l2-emulation}
160  * @cliexend
161  ?*/
162 /* *INDENT-OFF* */
163 VLIB_CLI_COMMAND (l2_emulation_show_node, static) = {
164   .path = "show interface l2 l2-emulation",
165   .short_help = "show interface l2 l2-emulation\n",
166   .function = l2_emulation_show,
167 };
168 /* *INDENT-ON* */
169
170 static clib_error_t *
171 l2_emulation_init (vlib_main_t * vm)
172 {
173   l2_emulation_main_t *em = &l2_emulation_main;
174   vlib_node_t *node;
175
176   node = vlib_get_node_by_name (vm, (u8 *) "l2-emulation");
177   em->l2_emulation_node_index = node->index;
178
179   /* Initialize the feature next-node indexes */
180   feat_bitmap_init_next_nodes (vm,
181                                em->l2_emulation_node_index,
182                                L2INPUT_N_FEAT,
183                                l2input_get_feat_names (),
184                                em->l2_input_feat_next);
185
186   return 0;
187 }
188
189 VLIB_INIT_FUNCTION (l2_emulation_init);
190
191 /*
192  * fd.io coding-style-patch-verification: ON
193  *
194  * Local Variables:
195  * eval: (c-set-style "gnu")
196  * End:
197  */