From 845560dc64c6031e53983511fee3aec2b365bf8e Mon Sep 17 00:00:00 2001 From: Yue Gao Date: Tue, 30 Jun 2026 13:40:40 -0700 Subject: [PATCH 1/2] Support setting interface speed via sai Signed-off-by: Yue Gao --- vslib/vpp/SwitchVpp.cpp | 4 ++ vslib/vpp/SwitchVpp.h | 6 +++ vslib/vpp/SwitchVppRif.cpp | 38 +++++++++++++++ vslib/vpp/vppxlate/SaiVppXlate.c | 83 ++++++++++++++++++++++++++++++++ vslib/vpp/vppxlate/SaiVppXlate.h | 2 + 5 files changed, 133 insertions(+) diff --git a/vslib/vpp/SwitchVpp.cpp b/vslib/vpp/SwitchVpp.cpp index f5644db42d..780f028ac2 100644 --- a/vslib/vpp/SwitchVpp.cpp +++ b/vslib/vpp/SwitchVpp.cpp @@ -2748,6 +2748,8 @@ sai_status_t SwitchVpp::refresh_port_oper_speed( { /* VPP reports link_speed in Kbps, SAI uses Mbps */ attr.value.u32 = vpp_speed_kbps / 1000; + SWSS_LOG_NOTICE("port oper speed from VPP: %s %u Kbps -> %u Mbps", + hwif_name.c_str(), vpp_speed_kbps, attr.value.u32); } else { @@ -2755,6 +2757,8 @@ sai_status_t SwitchVpp::refresh_port_oper_speed( attr.id = SAI_PORT_ATTR_SPEED; CHECK_STATUS(get(SAI_OBJECT_TYPE_PORT, port_id, 1, &attr)); + SWSS_LOG_NOTICE("port oper speed fallback to configured: %s %u Mbps", + hwif_name.c_str(), attr.value.u32); } } diff --git a/vslib/vpp/SwitchVpp.h b/vslib/vpp/SwitchVpp.h index 5d1eca0825..05aee1ad86 100644 --- a/vslib/vpp/SwitchVpp.h +++ b/vslib/vpp/SwitchVpp.h @@ -683,6 +683,12 @@ namespace saivs _In_ uint32_t vlan_id, _In_ uint32_t mtu); + // set ethernet interface link speed + sai_status_t vpp_set_port_speed ( + _In_ sai_object_id_t object_id, + _In_ uint32_t vlan_id, + _In_ uint32_t speed); + sai_status_t UpdatePort( _In_ sai_object_id_t object_id, _In_ uint32_t attr_count, diff --git a/vslib/vpp/SwitchVppRif.cpp b/vslib/vpp/SwitchVppRif.cpp index 7cbf368eae..59b3ad5d4a 100644 --- a/vslib/vpp/SwitchVppRif.cpp +++ b/vslib/vpp/SwitchVppRif.cpp @@ -397,6 +397,12 @@ void SwitchVpp::vppProcessEvents () SWSS_LOG_NOTICE("Checking for any VS events status %d", ret); while ((evp = vpp_ev_dequeue())) { if (evp->type == VPP_INTF_LINK_STATUS) { + if (evp->data.intf_status.link_up) { + /* Refresh cached link speed from VPP on link-up. + * The initial sw_interface_dump may have cached speed=0 + * if the link was down at startup. */ + vpp_refresh_interface_speed(evp->data.intf_status.hwif_name); + } asyncIntfStateUpdate(evp->data.intf_status.hwif_name, evp->data.intf_status.link_up); SWSS_LOG_NOTICE("Received port link event for %s state %s", @@ -570,6 +576,31 @@ sai_status_t SwitchVpp::vpp_set_interface_mtu ( return SAI_STATUS_SUCCESS; } +sai_status_t SwitchVpp::vpp_set_port_speed ( + _In_ sai_object_id_t object_id, + _In_ uint32_t vlan_id, + _In_ uint32_t speed) +{ + SWSS_LOG_ENTER(); + + if (is_ip_nbr_active() == false) { + return SAI_STATUS_SUCCESS; + } + + std::string ifname; + + if (vpp_get_hwif_name(object_id, vlan_id, ifname) == true) { + const char *hwif_name = ifname.c_str(); + + // SAI port speed is in Mbps, VPP link speed is in Kbps + uint32_t link_speed = speed * 1000; + + sw_interface_set_link_speed(hwif_name, link_speed); + SWSS_LOG_NOTICE("Updating port %s speed to %u Mbps", hwif_name, speed); + } + return SAI_STATUS_SUCCESS; +} + sai_status_t SwitchVpp::UpdatePort( _In_ sai_object_id_t object_id, _In_ uint32_t attr_count, @@ -627,6 +658,13 @@ sai_status_t SwitchVpp::UpdatePort( vpp_set_port_mtu(object_id, 0, attr_type->value.u32); } + attr_type = sai_metadata_get_attr_by_id(SAI_PORT_ATTR_SPEED, attr_count, attr_list); + + if (attr_type != NULL) + { + vpp_set_port_speed(object_id, 0, attr_type->value.u32); + } + return SAI_STATUS_SUCCESS; } diff --git a/vslib/vpp/vppxlate/SaiVppXlate.c b/vslib/vpp/vppxlate/SaiVppXlate.c index 78f1faa18d..ca1a3abb27 100644 --- a/vslib/vpp/vppxlate/SaiVppXlate.c +++ b/vslib/vpp/vppxlate/SaiVppXlate.c @@ -1385,6 +1385,7 @@ static void vpp_base_vpe_init(void) _(INTERFACE_MSG_ID(SW_INTERFACE_ADD_DEL_ADDRESS_REPLY), sw_interface_add_del_address_reply) \ _(INTERFACE_MSG_ID(SW_INTERFACE_SET_FLAGS_REPLY), sw_interface_set_flags_reply) \ _(INTERFACE_MSG_ID(SW_INTERFACE_SET_MTU_REPLY), sw_interface_set_mtu_reply) \ + _(INTERFACE_MSG_ID(SW_INTERFACE_SET_LINK_SPEED_REPLY), sw_interface_set_link_speed_reply) \ _(INTERFACE_MSG_ID(SW_INTERFACE_SET_MAC_ADDRESS_REPLY), sw_interface_set_mac_address_reply) \ _(INTERFACE_MSG_ID(SW_INTERFACE_SET_UNNUMBERED_REPLY), sw_interface_set_unnumbered_reply) \ _(INTERFACE_MSG_ID(HW_INTERFACE_SET_MTU_REPLY), hw_interface_set_mtu_reply) \ @@ -3009,6 +3010,48 @@ int interface_get_state (const char *hwif_name, bool *link_is_up) return ret; } +int vpp_refresh_interface_speed (const char *hwif_name) +{ + vat_main_t *vam = &vat_main; + vl_api_sw_interface_dump_t *mp; + vl_api_control_ping_t *mp_ping; + int ret; + + VPP_LOCK(); + + __plugin_msg_base = interface_msg_id_base; + + M (SW_INTERFACE_DUMP, mp); + + u32 idx = get_swif_idx(vam, hwif_name); + if (idx == (u32) -1) { + SAIVPP_ERROR("%s: unable to get sw_index for %s", __func__, hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } + mp->sw_if_index = htonl(idx); + /* context=0 so the details handler takes the normal path and + * updates link_speed_by_sw_index. */ + + S (mp); + + __plugin_msg_base = memclnt_msg_id_base; + PING (NULL, mp_ping); + S (mp_ping); + + WR (ret); + + if (ret) { + SAIVPP_ERROR("%s: dump failed(%d) for %s (idx %u)", __func__, ret, hwif_name, idx); + } else { + SAIVPP_INFO("%s: refreshed speed for %s (idx %u)", __func__, hwif_name, idx); + } + + VPP_UNLOCK(); + + return ret; +} + int vpp_get_interface_speed (const char *hwif_name, uint32_t *speed) { vat_main_t *vam = &vat_main; @@ -3101,6 +3144,46 @@ int sw_interface_set_mtu (const char *hwif_name, uint32_t mtu) return ret; } +int sw_interface_set_link_speed (const char *hwif_name, uint32_t link_speed) +{ + vat_main_t *vam = &vat_main; + vl_api_sw_interface_set_link_speed_t *mp; + int ret; + + VPP_LOCK(); + + __plugin_msg_base = interface_msg_id_base; + + M (SW_INTERFACE_SET_LINK_SPEED, mp); + if (hwif_name) { + u32 idx; + + idx = get_swif_idx(vam, hwif_name); + if (idx != (u32) -1) { + mp->sw_if_index = htonl(idx); + } else { + SAIVPP_ERROR("Unable to get sw_index for %s\n", hwif_name); + VPP_UNLOCK(); + return -EINVAL; + } + } else { + VPP_UNLOCK(); + return -EINVAL; + } + mp->link_speed = htonl(link_speed); + + S (mp); + + WR (ret); + + if (ret) { SAIVPP_ERROR("%s failed(%d) %s link_speed %u", __func__, ret, hwif_name, link_speed); } + else { SAIVPP_INFO("%s %s link_speed %u", __func__, hwif_name, link_speed); } + + VPP_UNLOCK(); + + return ret; +} + int sw_interface_set_mac (const char *hwif_name, uint8_t *mac_address) { vat_main_t *vam = &vat_main; diff --git a/vslib/vpp/vppxlate/SaiVppXlate.h b/vslib/vpp/vppxlate/SaiVppXlate.h index bcde54095f..9dd8e9a7df 100644 --- a/vslib/vpp/vppxlate/SaiVppXlate.h +++ b/vslib/vpp/vppxlate/SaiVppXlate.h @@ -299,6 +299,7 @@ typedef enum { extern int interface_set_state (const char *hwif_name, bool is_up); extern int hw_interface_set_mtu(const char *hwif_name, uint32_t mtu); extern int sw_interface_set_mtu(const char *hwif_name, uint32_t mtu); + extern int sw_interface_set_link_speed(const char *hwif_name, uint32_t link_speed); extern int sw_interface_set_mac(const char *hwif_name, uint8_t *mac_address); extern int sw_interface_ip6_enable_disable(const char *hwif_name, bool enable); extern int ip_vrf_add(uint32_t vrf_id, const char *vrf_name, bool is_ipv6); @@ -323,6 +324,7 @@ typedef enum { extern int vpp_tunterm_acl_interface_add_del (uint32_t tunterm_index, bool is_bind, const char *hwif_name); extern int interface_get_state(const char *hwif_name, bool *link_is_up); + extern int vpp_refresh_interface_speed(const char *hwif_name); extern int vpp_get_interface_speed(const char *hwif_name, uint32_t *speed); extern int vpp_sync_for_events(); extern int vpp_bridge_domain_add_del(uint32_t bridge_id, bool is_add); From 741cfc2dce1bafbda8e29ee122edbe338004ebb1 Mon Sep 17 00:00:00 2001 From: Yue Gao Date: Fri, 3 Jul 2026 11:45:32 -0700 Subject: [PATCH 2/2] Add missing function Signed-off-by: Yue Gao --- vslib/vpp/vppxlate/SaiVppXlate.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/vslib/vpp/vppxlate/SaiVppXlate.c b/vslib/vpp/vppxlate/SaiVppXlate.c index ca1a3abb27..867d7195e4 100644 --- a/vslib/vpp/vppxlate/SaiVppXlate.c +++ b/vslib/vpp/vppxlate/SaiVppXlate.c @@ -870,6 +870,12 @@ vl_api_sw_interface_set_mtu_reply_t_handler (vl_api_sw_interface_set_mtu_reply_t set_reply_status(retval); } static void +vl_api_sw_interface_set_link_speed_reply_t_handler (vl_api_sw_interface_set_link_speed_reply_t *msg) +{ + int retval = (int)ntohl((uint32_t)msg->retval); + set_reply_status(retval); +} +static void vl_api_sw_interface_set_mac_address_reply_t_handler (vl_api_sw_interface_set_mac_address_reply_t *msg) { int retval = (int)ntohl((uint32_t)msg->retval);