1 /* SPDX-License-Identifier: Apache-2.0
2 * Copyright (c) 2023 Cisco Systems, Inc.
6 #include <vnet/ethernet/ethernet.h>
7 #include <vnet/dev/dev.h>
8 #include <vnet/dev/counters.h>
9 #include <vnet/dev/log.h>
10 #include <vnet/flow/flow.h>
12 VLIB_REGISTER_LOG_CLASS (dev_log, static) = {
14 .subclass_name = "handler",
18 vnet_dev_port_set_max_frame_size (vnet_main_t *vnm, vnet_hw_interface_t *hw,
21 vlib_main_t *vm = vlib_get_main ();
22 vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hw->dev_instance);
25 vnet_dev_port_cfg_change_req_t req = {
26 .type = VNET_DEV_PORT_CFG_MAX_FRAME_SIZE,
27 .max_frame_size = frame_size,
30 log_debug (p->dev, "size %u", frame_size);
32 rv = vnet_dev_port_cfg_change_req_validate (vm, p, &req);
33 if (rv == VNET_DEV_ERR_NO_CHANGE)
36 if (rv != VNET_DEV_OK)
37 return vnet_dev_port_err (vm, p, rv,
38 "new max frame size is not valid for port");
40 if ((rv = vnet_dev_process_port_cfg_change_req (vm, p, &req)) != VNET_DEV_OK)
41 return vnet_dev_port_err (vm, p, rv,
42 "device failed to change max frame size");
48 vnet_dev_port_eth_flag_change (vnet_main_t *vnm, vnet_hw_interface_t *hw,
51 vlib_main_t *vm = vlib_get_main ();
52 vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hw->dev_instance);
55 vnet_dev_port_cfg_change_req_t req = {
56 .type = VNET_DEV_PORT_CFG_PROMISC_MODE,
61 case ETHERNET_INTERFACE_FLAG_DEFAULT_L3:
62 log_debug (p->dev, "promisc off");
64 case ETHERNET_INTERFACE_FLAG_ACCEPT_ALL:
65 log_debug (p->dev, "promisc on");
72 rv = vnet_dev_port_cfg_change_req_validate (vm, p, &req);
73 if (rv == VNET_DEV_ERR_NO_CHANGE)
76 if (rv != VNET_DEV_OK)
79 rv = vnet_dev_process_port_cfg_change_req (vm, p, &req);
80 if (rv == VNET_DEV_OK || rv == VNET_DEV_ERR_NO_CHANGE)
86 vnet_dev_port_mac_change (vnet_hw_interface_t *hi, const u8 *old,
89 vlib_main_t *vm = vlib_get_main ();
90 vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hi->dev_instance);
93 vnet_dev_port_cfg_change_req_t req = {
94 .type = VNET_DEV_PORT_CFG_CHANGE_PRIMARY_HW_ADDR,
97 vnet_dev_set_hw_addr_eth_mac (&req.addr, new);
99 log_debug (p->dev, "new mac %U", format_vnet_dev_hw_addr, &req.addr);
101 rv = vnet_dev_port_cfg_change_req_validate (vm, p, &req);
102 if (rv == VNET_DEV_ERR_NO_CHANGE)
105 if (rv != VNET_DEV_OK)
106 return vnet_dev_port_err (vm, p, rv, "hw address is not valid for port");
108 if ((rv = vnet_dev_process_port_cfg_change_req (vm, p, &req)) != VNET_DEV_OK)
109 return vnet_dev_port_err (vm, p, rv, "device failed to change hw address");
115 vnet_dev_add_del_mac_address (vnet_hw_interface_t *hi, const u8 *address,
118 vlib_main_t *vm = vlib_get_main ();
119 vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hi->dev_instance);
122 vnet_dev_port_cfg_change_req_t req = {
123 .type = is_add ? VNET_DEV_PORT_CFG_ADD_SECONDARY_HW_ADDR :
124 VNET_DEV_PORT_CFG_REMOVE_SECONDARY_HW_ADDR,
127 vnet_dev_set_hw_addr_eth_mac (&req.addr, address);
129 log_debug (p->dev, "received (addr %U is_add %u", format_vnet_dev_hw_addr,
132 rv = vnet_dev_port_cfg_change_req_validate (vm, p, &req);
133 if (rv != VNET_DEV_OK)
134 return vnet_dev_port_err (vm, p, rv,
135 "provided secondary hw addresses cannot "
138 if ((rv = vnet_dev_process_port_cfg_change_req (vm, p, &req)) != VNET_DEV_OK)
139 return vnet_dev_port_err (
140 vm, p, rv, "device failed to add/remove secondary hw address");
146 vnet_dev_flow_ops_fn (vnet_main_t *vnm, vnet_flow_dev_op_t op,
147 u32 dev_instance, u32 flow_index, uword *private_data)
149 vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (dev_instance);
150 log_warn (p->dev, "unsupported request for flow_ops received");
151 return VNET_FLOW_ERROR_NOT_SUPPORTED;
155 vnet_dev_interface_set_rss_queues (vnet_main_t *vnm, vnet_hw_interface_t *hi,
156 clib_bitmap_t *bitmap)
158 vnet_dev_port_t *p = vnet_dev_get_port_from_dev_instance (hi->dev_instance);
159 log_warn (p->dev, "unsupported request for flow_ops received");
160 return vnet_error (VNET_ERR_UNSUPPORTED, "not implemented");
164 vnet_dev_clear_hw_interface_counters (u32 instance)
166 vnet_dev_port_t *port = vnet_dev_get_port_from_dev_instance (instance);
167 vlib_main_t *vm = vlib_get_main ();
169 vnet_dev_process_call_port_op_no_rv (vm, port, vnet_dev_port_clear_counters);
173 vnet_dev_rx_mode_change_fn (vnet_main_t *vnm, u32 hw_if_index, u32 qid,
174 vnet_hw_if_rx_mode mode)
176 return clib_error_return (0, "not supported");
180 vnet_dev_set_interface_next_node (vnet_main_t *vnm, u32 hw_if_index,
183 vlib_main_t *vm = vlib_get_main ();
184 vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
185 vnet_dev_port_t *port =
186 vnet_dev_get_port_from_dev_instance (hw->dev_instance);
187 int runtime_update = 0;
189 if (node_index == ~0)
191 port->intf.redirect_to_node_next_index = 0;
192 if (port->intf.feature_arc == 0)
194 port->intf.rx_next_index =
195 vnet_dev_default_next_index_by_port_type[port->attr.type];
198 port->intf.redirect_to_node = 0;
202 u16 next_index = vlib_node_add_next (vlib_get_main (),
203 port_rx_eth_node.index, node_index);
204 port->intf.redirect_to_node_next_index = next_index;
205 if (port->intf.feature_arc == 0)
207 port->intf.rx_next_index = next_index;
210 port->intf.redirect_to_node = 1;
212 port->intf.rx_next_index =
214 vnet_dev_default_next_index_by_port_type[port->attr.type] :
219 foreach_vnet_dev_port_rx_queue (rxq, port)
220 vnet_dev_rx_queue_rt_request (
221 vm, rxq, (vnet_dev_rx_queue_rt_req_t){ .update_next_index = 1 });
222 log_debug (port->dev, "runtime update requested due to chgange in "
223 "reditect-to-next configuration");