From 11771b124c02ddb90f30528457bf0cb9d31c6447 Mon Sep 17 00:00:00 2001 From: bendrapubalareddy Date: Tue, 27 Feb 2024 06:57:42 -0500 Subject: [PATCH 1/4] issue 90: SONiC-VPP LAG layer 2 support Files Modified: platform/saivpp/vpplib/SwitchStateBase.cpp platform/saivpp/vpplib/SwitchStateBase.h platform/saivpp/vpplib/SwitchStateBaseFdb.cpp platform/saivpp/vpplib/vppxlate/SaiVppXlate.c platform/saivpp/vpplib/vppxlate/SaiVppXlate.h Signed-of-by: bendrapubalareddy bala.balareddy@gmail.com --- platform/saivpp/vpplib/SwitchStateBase.cpp | 27 ++ platform/saivpp/vpplib/SwitchStateBase.h | 29 ++ platform/saivpp/vpplib/SwitchStateBaseFdb.cpp | 334 ++++++++++++++++-- platform/saivpp/vpplib/vppxlate/SaiVppXlate.c | 254 ++++++++++++- platform/saivpp/vpplib/vppxlate/SaiVppXlate.h | 21 ++ 5 files changed, 644 insertions(+), 21 deletions(-) diff --git a/platform/saivpp/vpplib/SwitchStateBase.cpp b/platform/saivpp/vpplib/SwitchStateBase.cpp index 646133e..dc154e7 100644 --- a/platform/saivpp/vpplib/SwitchStateBase.cpp +++ b/platform/saivpp/vpplib/SwitchStateBase.cpp @@ -253,6 +253,21 @@ sai_status_t SwitchStateBase::create( return createVlanMember(object_id, switch_id, attr_count, attr_list); } + if (object_type == SAI_OBJECT_TYPE_LAG ) + { + sai_object_id_t object_id; + sai_deserialize_object_id(serializedObjectId, object_id); + SWSS_LOG_NOTICE("BALA: create serialized: entry %s objectType %d attr count %d", serializedObjectId.c_str(), object_type, attr_count); + return createLag(object_id, switch_id, attr_count, attr_list); + } + if (object_type == SAI_OBJECT_TYPE_LAG_MEMBER) + { + sai_object_id_t object_id; + sai_deserialize_object_id(serializedObjectId, object_id); + SWSS_LOG_NOTICE("create serialized: entry %s objectType %d attr count %d", serializedObjectId.c_str(), object_type, attr_count); + return createLagMember(object_id, switch_id, attr_count, attr_list); + } + return create_internal(object_type, serializedObjectId, switch_id, attr_count, attr_list); } @@ -527,6 +542,18 @@ sai_status_t SwitchStateBase::remove( sai_deserialize_object_id(serializedObjectId, objectId); return removeVlanMember(objectId); } + else if (object_type == SAI_OBJECT_TYPE_LAG) + { + sai_object_id_t objectId; + sai_deserialize_object_id(serializedObjectId, objectId); + return removeLag(objectId); + } + else if (object_type == SAI_OBJECT_TYPE_LAG_MEMBER) + { + sai_object_id_t objectId; + sai_deserialize_object_id(serializedObjectId, objectId); + return removeLagMember(objectId); + } return remove_internal(object_type, serializedObjectId); } diff --git a/platform/saivpp/vpplib/SwitchStateBase.h b/platform/saivpp/vpplib/SwitchStateBase.h index 87f056b..473873e 100644 --- a/platform/saivpp/vpplib/SwitchStateBase.h +++ b/platform/saivpp/vpplib/SwitchStateBase.h @@ -163,6 +163,32 @@ namespace saivpp _In_ const sai_attribute_t *attr_list); sai_status_t vpp_delete_bvi_interface( _In_ sai_object_id_t bvi_obj_id); + sai_status_t createLag( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + sai_status_t vpp_create_lag( + _In_ sai_object_id_t lag_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + sai_status_t removeLag( + _In_ sai_object_id_t lag_oid); + sai_status_t vpp_remove_lag( + _In_ sai_object_id_t lag_oid); + sai_status_t createLagMember( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + sai_status_t vpp_create_lag_member( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list); + sai_status_t removeLagMember( + _In_ sai_object_id_t lag_member_oid); + sai_status_t vpp_remove_lag_member( + _In_ sai_object_id_t lag_member_oid); + protected: virtual sai_status_t create_port_dependencies( @@ -1016,6 +1042,8 @@ namespace saivpp void populate_if_mapping(); const char *tap_to_hwif_name(const char *name); const char *hwif_to_tap_name(const char *name); + uint32_t lag_to_bond_if_idx (const sai_object_id_t lag_id); + int remove_lag_to_bond_entry (const sai_object_id_t lag_id); void vppProcessEvents (); void startVppEventsThread(); @@ -1029,6 +1057,7 @@ namespace saivpp bool m_run_vpp_events_thread = true; bool VppEventsThreadStarted = false; std::shared_ptr m_vpp_thread; + std::map m_lag_bond_map; private: static int currentMaxInstance; diff --git a/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp b/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp index 4ba2b90..1663794 100644 --- a/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp +++ b/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp @@ -678,7 +678,7 @@ sai_status_t SwitchStateBase::vpp_create_vlan_member( if (obj_type != SAI_OBJECT_TYPE_BRIDGE_PORT) { - SWSS_LOG_ERROR("SAI_VLAN_MEMBER_ATTR_BRIDGE_PORT_ID=%s expected to be PORT but is: %s", + SWSS_LOG_ERROR("SAI_VLAN_MEMBER_ATTR_BRIDGE_PORT_ID=%s expected to be BRIDGE PORT but is: %s", sai_serialize_object_id(br_port_id).c_str(), sai_serialize_object_type(obj_type).c_str()); @@ -686,28 +686,43 @@ sai_status_t SwitchStateBase::vpp_create_vlan_member( } const char *hwifname = nullptr; + uint32_t lag_swif_idx; + auto br_port_attrs = m_objectHash.at(SAI_OBJECT_TYPE_BRIDGE_PORT).at(sai_serialize_object_id(br_port_id)); auto meta = sai_metadata_get_attr_metadata(SAI_OBJECT_TYPE_BRIDGE_PORT, SAI_BRIDGE_PORT_ATTR_PORT_ID); auto bp_attr = br_port_attrs[meta->attridname]; auto port_id = bp_attr->getAttr()->value.oid; obj_type = objectTypeQuery(port_id); - if (obj_type != SAI_OBJECT_TYPE_PORT) + if (obj_type != SAI_OBJECT_TYPE_PORT && obj_type != SAI_OBJECT_TYPE_LAG ) { - SWSS_LOG_NOTICE("SAI_BRIDGE_PORT_ATTR_PORT_ID=%s expected to be PORT but is: %s", + SWSS_LOG_NOTICE("SAI_BRIDGE_PORT_ATTR_PORT_ID=%s expected to be PORT or LAG but is: %s", sai_serialize_object_id(port_id).c_str(), sai_serialize_object_type(obj_type).c_str()); return SAI_STATUS_FAILURE; } - std::string if_name; - bool found = getTapNameFromPortId(port_id, if_name); - if (found == true) + if (obj_type == SAI_OBJECT_TYPE_PORT) { - hwifname = tap_to_hwif_name(if_name.c_str()); - }else { - SWSS_LOG_NOTICE("No ports found for bridge port id :%s",sai_serialize_object_id(br_port_id).c_str()); - return SAI_STATUS_FAILURE; + std::string if_name; + bool found = getTapNameFromPortId(port_id, if_name); + if (found == true) + { + hwifname = tap_to_hwif_name(if_name.c_str()); + }else { + SWSS_LOG_NOTICE("No ports found for bridge port id :%s",sai_serialize_object_id(br_port_id).c_str()); + return SAI_STATUS_FAILURE; + } + } else if (obj_type == SAI_OBJECT_TYPE_LAG) { + lag_swif_idx = lag_to_bond_if_idx(port_id); + SWSS_LOG_NOTICE("lag swif idx :%d",lag_swif_idx); + hwifname = vpp_get_swif_name(lag_swif_idx); + SWSS_LOG_NOTICE("lag swif idx :%d swif_name:%s",lag_swif_idx, hwifname); + if (hwifname == NULL) + { + SWSS_LOG_NOTICE("LAG is not found for bridge port id :%s",sai_serialize_object_id(br_port_id).c_str()); + return SAI_STATUS_FAILURE; + } } auto attr_vlan_member = sai_metadata_get_attr_by_id(SAI_VLAN_MEMBER_ATTR_VLAN_ID, attr_count, attr_list); @@ -865,24 +880,37 @@ sai_status_t SwitchStateBase::vpp_remove_vlan_member( auto port_id = bp_attr->getAttr()->value.oid; obj_type = objectTypeQuery(port_id); - if (obj_type != SAI_OBJECT_TYPE_PORT) + if (obj_type != SAI_OBJECT_TYPE_PORT && obj_type != SAI_OBJECT_TYPE_LAG) { - SWSS_LOG_NOTICE("SAI_BRIDGE_PORT_ATTR_PORT_ID=%s expected to be PORT but is: %s", + SWSS_LOG_NOTICE("SAI_BRIDGE_PORT_ATTR_PORT_ID=%s expected to be PORT or LAG but is: %s", sai_serialize_object_id(port_id).c_str(), sai_serialize_object_type(obj_type).c_str()); return SAI_STATUS_FAILURE; } - std::string if_name; - bool found = getTapNameFromPortId(port_id, if_name); - if (found == true) + + if (obj_type == SAI_OBJECT_TYPE_PORT) { - hw_ifname = tap_to_hwif_name(if_name.c_str()); - }else { - SWSS_LOG_NOTICE("No ports found for bridge port id :%s",sai_serialize_object_id(br_port_oid).c_str()); - return SAI_STATUS_FAILURE; + std::string if_name; + bool found = getTapNameFromPortId(port_id, if_name); + if (found == true) + { + hw_ifname = tap_to_hwif_name(if_name.c_str()); + }else { + SWSS_LOG_NOTICE("No ports found for bridge port id :%s",sai_serialize_object_id(br_port_oid).c_str()); + return SAI_STATUS_FAILURE; + } + } else if (obj_type == SAI_OBJECT_TYPE_LAG) { + uint32_t lag_swif_idx = lag_to_bond_if_idx(port_id); + SWSS_LOG_NOTICE("lag swif idx :%d",lag_swif_idx); + hw_ifname = vpp_get_swif_name(lag_swif_idx); + SWSS_LOG_NOTICE("lag swif idx :%d swif_name:%s",lag_swif_idx, hw_ifname); + if (hw_ifname == NULL) + { + SWSS_LOG_NOTICE("LAG port is not found for bridge port id :%s",sai_serialize_object_id(port_id).c_str()); + return SAI_STATUS_FAILURE; + } } - attr.id = SAI_VLAN_MEMBER_ATTR_VLAN_TAGGING_MODE; status = get(SAI_OBJECT_TYPE_VLAN_MEMBER, vlan_member_oid, 1, &attr); @@ -1082,3 +1110,269 @@ sai_status_t SwitchStateBase::vpp_delete_bvi_interface( return SAI_STATUS_SUCCESS; } + +uint32_t SwitchStateBase::lag_to_bond_if_idx (const sai_object_id_t lag_id) +{ + auto it = m_lag_bond_map.find(lag_id); + + if (it == m_lag_bond_map.end()) + { + SWSS_LOG_ERROR("failed to find bond if idx for lag id: %x",lag_id); + return ~0; + } + return it->second; +} + +int SwitchStateBase::remove_lag_to_bond_entry(const sai_object_id_t lag_oid) +{ + auto it = m_lag_bond_map.find(lag_oid); + + if (it == m_lag_bond_map.end()) + { + SWSS_LOG_ERROR("failed to find lag swif index for : %s", sai_serialize_object_id(lag_oid).c_str()); + return ~0; + } + + SWSS_LOG_NOTICE("Removing lag object swif index: %s", sai_serialize_object_id(lag_oid).c_str()); + m_lag_bond_map.erase(it); + return 0; +} + +sai_status_t SwitchStateBase:: createLag( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + auto sid = sai_serialize_object_id(object_id); + CHECK_STATUS(create_internal(SAI_OBJECT_TYPE_LAG, sid, switch_id, attr_count, attr_list)); + return vpp_create_lag(object_id, attr_count, attr_list); + +} + +sai_status_t SwitchStateBase::vpp_create_lag( + _In_ sai_object_id_t lag_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + uint32_t bond_id, mode, lb; + int32_t ret; + uint32_t swif_idx = ~0; + const char *hw_ifname; + SWSS_LOG_ENTER(); + + //set mode and lb + mode = VPP_BOND_API_MODE_ROUND_ROBIN; + lb = VPP_BOND_API_LB_ALGO_L2; + bond_id = ~0; + + ret = create_bond_interface(bond_id, mode, lb, &swif_idx); + + if (ret) + { + SWSS_LOG_ERROR("vpp bond interface create failed\n"); + return SAI_STATUS_SUCCESS; + } + + SWSS_LOG_NOTICE("Bond interfae if index:%d\n", swif_idx); + //update the lag to bond map + m_lag_bond_map[lag_id] = swif_idx; + refresh_interfaces_list(); + + // Set the bond interface state up + hw_ifname = vpp_get_swif_name(swif_idx); + SWSS_LOG_NOTICE("Setting lag hw interface state to up :%s",hw_ifname); + interface_set_state(hw_ifname, true); + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchStateBase:: removeLag( + _In_ sai_object_id_t lag_oid) +{ + SWSS_LOG_ENTER(); + + vpp_remove_lag(lag_oid); + auto sid = sai_serialize_object_id(lag_oid); + CHECK_STATUS(remove_internal(SAI_OBJECT_TYPE_LAG, sid)); + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchStateBase::vpp_remove_lag( + _In_ sai_object_id_t lag_oid) +{ + SWSS_LOG_ENTER(); + + uint32_t lag_swif_idx = lag_to_bond_if_idx(lag_oid); + SWSS_LOG_NOTICE("lag swif idx :%d",lag_swif_idx); + auto lag_ifname = vpp_get_swif_name(lag_swif_idx); + SWSS_LOG_NOTICE("lag swif idx :%d swif_name:%s",lag_swif_idx, lag_ifname); + if (lag_ifname == NULL) + { + SWSS_LOG_NOTICE("LAG interface name is not found for LAG PORT :%s",sai_serialize_object_id(lag_oid).c_str()); + return SAI_STATUS_FAILURE; + } + + //Delete the Bond interface + delete_bond_interface(lag_ifname); + remove_lag_to_bond_entry(lag_oid); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchStateBase:: createLagMember( + _In_ sai_object_id_t object_id, + _In_ sai_object_id_t switch_id, + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + SWSS_LOG_ENTER(); + + auto sid = sai_serialize_object_id(object_id); + + CHECK_STATUS(create_internal(SAI_OBJECT_TYPE_LAG_MEMBER, sid, switch_id, attr_count, attr_list)); + return vpp_create_lag_member(attr_count, attr_list); +} + +sai_status_t SwitchStateBase::vpp_create_lag_member( + _In_ uint32_t attr_count, + _In_ const sai_attribute_t *attr_list) +{ + bool is_long_timeout = false; + bool is_passive = false; + uint32_t bond_if_idx; + sai_object_id_t lag_oid, lag_port_oid; + SWSS_LOG_ENTER(); + + //Get the bond interface index from attr SAI_LAG_MEMBER_ATTR_LAG_ID + auto attr_type = sai_metadata_get_attr_by_id(SAI_LAG_MEMBER_ATTR_LAG_ID, attr_count, attr_list); + if (attr_type == NULL) + { + SWSS_LOG_ERROR("attr SAI_LAG_MEMBER_ATTR_LAG_ID was not passed"); + return SAI_STATUS_FAILURE; + } + lag_oid = attr_type->value.oid; + sai_object_type_t obj_type = objectTypeQuery(lag_oid); + + if (obj_type != SAI_OBJECT_TYPE_LAG) + { + SWSS_LOG_ERROR(" SAI_LAG_MEMBER_ATTR_LAG_ID = %s expected to be LAG ID but is: %s", + sai_serialize_object_id(lag_oid).c_str(), + sai_serialize_object_type(obj_type).c_str()); + return SAI_STATUS_FAILURE; + } + bond_if_idx = lag_to_bond_if_idx(lag_oid); + SWSS_LOG_NOTICE("bond if index is %d\n",bond_if_idx); + + attr_type = sai_metadata_get_attr_by_id(SAI_LAG_MEMBER_ATTR_PORT_ID, attr_count, attr_list); + + if (attr_type == NULL) + { + SWSS_LOG_ERROR("attr SAI_LAG_MEMBER_ATTR_PORT_ID was not present\n"); + return SAI_STATUS_FAILURE; + } + + lag_port_oid = attr_type->value.oid; + SWSS_LOG_NOTICE("lag port id is %s",sai_serialize_object_id(lag_port_oid).c_str()); + obj_type = objectTypeQuery(lag_port_oid); + if (obj_type != SAI_OBJECT_TYPE_PORT) + { + SWSS_LOG_NOTICE("SAI_BRIDGE_PORT_ATTR_PORT_ID=%s expected to be PORT but is: %s", + sai_serialize_object_id(lag_port_oid).c_str(), + sai_serialize_object_type(obj_type).c_str()); + return SAI_STATUS_FAILURE; + } + + std::string if_name; + bool found = getTapNameFromPortId(lag_port_oid, if_name); + const char *hwifname; + if (found == true) + { + hwifname = tap_to_hwif_name(if_name.c_str()); + SWSS_LOG_NOTICE("hwif name for port is %s",hwifname); + }else { + SWSS_LOG_NOTICE("No ports found for lag port id :%s",sai_serialize_object_id(lag_port_oid).c_str()); + return SAI_STATUS_FAILURE; + } + + create_bond_member(bond_if_idx, hwifname,is_passive,is_long_timeout); + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchStateBase::removeLagMember( + _In_ sai_object_id_t lag_member_oid) +{ + SWSS_LOG_ENTER(); + + vpp_remove_lag_member(lag_member_oid); + + auto sid = sai_serialize_object_id(lag_member_oid); + + CHECK_STATUS(remove_internal(SAI_OBJECT_TYPE_LAG_MEMBER, sid)); + + return SAI_STATUS_SUCCESS; +} + +sai_status_t SwitchStateBase::vpp_remove_lag_member( + _In_ sai_object_id_t lag_member_oid) +{ + SWSS_LOG_ENTER(); + + sai_attribute_t attr; + + attr.id = SAI_LAG_MEMBER_ATTR_LAG_ID; + + sai_status_t status = get(SAI_OBJECT_TYPE_LAG_MEMBER, lag_member_oid, 1, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("attr SAI_LAG_MEMBER_ATTR_LAG_ID is not present"); + + return SAI_STATUS_FAILURE; + } + sai_object_id_t lag_oid = attr.value.oid; + + sai_object_type_t obj_type = objectTypeQuery(lag_oid); + + if (obj_type != SAI_OBJECT_TYPE_LAG) + { + SWSS_LOG_ERROR("attr SAI_LAG_MEMBER_ATTR_LAG_ID is not valid"); + return SAI_STATUS_FAILURE; + } + + attr.id = SAI_LAG_MEMBER_ATTR_PORT_ID; + + status = get(SAI_OBJECT_TYPE_LAG_MEMBER, lag_member_oid, 1, &attr); + + if (status != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("attr SAI_LAG_MEMBER_ATTR_PORT_ID is not present"); + + return SAI_STATUS_FAILURE; + } + sai_object_id_t port_oid = attr.value.oid; + + obj_type = objectTypeQuery(port_oid); + + if (obj_type != SAI_OBJECT_TYPE_PORT) + { + SWSS_LOG_ERROR("attr SAI_LAG_MEMBER_ATTR_PORT_ID is not valid"); + return SAI_STATUS_FAILURE; + } + + std::string if_name; + bool found = getTapNameFromPortId(port_oid, if_name); + const char *lag_member_ifname; + if (found == true) + { + lag_member_ifname = tap_to_hwif_name(if_name.c_str()); + SWSS_LOG_NOTICE("hwif name for port is %s",lag_member_ifname); + } else { + SWSS_LOG_NOTICE("No ports found for lag port id :%s",sai_serialize_object_id(port_oid).c_str()); + return SAI_STATUS_FAILURE; + } + + delete_bond_member(lag_member_ifname); + return SAI_STATUS_SUCCESS; +} diff --git a/platform/saivpp/vpplib/vppxlate/SaiVppXlate.c b/platform/saivpp/vpplib/vppxlate/SaiVppXlate.c index 8cb2d73..57ca20f 100644 --- a/platform/saivpp/vpplib/vppxlate/SaiVppXlate.c +++ b/platform/saivpp/vpplib/vppxlate/SaiVppXlate.c @@ -53,6 +53,9 @@ #include #include +#include +#include + /* l2 API inclusion */ #define vl_typedefs @@ -187,6 +190,28 @@ #include #undef vl_api_version +/* BOND API inclusion */ + +#define vl_typedefs +#include +#undef vl_typedefs + +#define vl_endianfun +#include +#undef vl_endianfun + +#define vl_printfun +#include +#undef vl_printfun + +#define vl_calcsizefun +#include +#undef vl_calcsizefun + +#define vl_api_version(n, v) static u32 bond_api_version = v; +#include +#undef vl_api_version + /* memclnt API inclusion */ #define vl_typedefs /* define message structures */ @@ -675,6 +700,49 @@ vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t *mp) return; } +static void +vl_api_bond_create_reply_t_handler (vl_api_bond_create_reply_t *msg) +{ + set_reply_status(ntohl(msg->retval)); + + if (msg->context) { + u32 *swif_idx = (u32 *) get_index_ptr(msg->context); + *swif_idx = ntohl(msg->sw_if_index); + } + + SAIVPP_WARN("bond add %s(%d)", msg->retval ? "failed" : "successful", msg->retval); + if (!msg->retval) + { + uint32_t bond_if_index = ntohl(msg->sw_if_index); + SAIVPP_WARN("created bond if index%d", bond_if_index); + } + //SAIVPP_ERROR("l2 add del reply handler called %s(%d)",msg->retval ? "failed" : "successful", msg->retval); + +} + +static void +vl_api_bond_delete_reply_t_handler (vl_api_bond_delete_reply_t *msg) +{ + set_reply_status(ntohl(msg->retval)); + + SAIVPP_WARN("bond delete %s(%d)", msg->retval ? "failed" : "successful", msg->retval); +} + +static void +vl_api_bond_add_member_reply_t_handler (vl_api_bond_add_member_reply_t *msg) +{ + set_reply_status(ntohl(msg->retval)); + + SAIVPP_WARN("bond add member %s(%d)", msg->retval ? "failed" : "successful", msg->retval); +} + +static void +vl_api_bond_detach_member_reply_t_handler (vl_api_bond_detach_member_reply_t *msg) +{ + set_reply_status(ntohl(msg->retval)); + + SAIVPP_WARN("bond detach member %s(%d)", msg->retval ? "failed" : "successful", msg->retval); +} #define vl_api_get_first_msg_id_reply_t_handler vl_noop_handler #define vl_api_get_first_msg_id_reply_t_handler_json vl_noop_handler @@ -686,6 +754,7 @@ vl_api_bridge_domain_details_t_handler (vl_api_bridge_domain_details_t *mp) static u16 interface_msg_id_base, memclnt_msg_id_base, __plugin_msg_base; static u16 l2_msg_id_base; +static u16 bond_msg_id_base; static void vpp_base_vpe_init(void) { @@ -716,6 +785,10 @@ static void vpp_base_vpe_init(void) #define L2_MSG_ID(id) \ (VL_API_##id + l2_msg_id_base) +#define BOND_MSG_ID(id) \ + (VL_API_##id + bond_msg_id_base) + + #define foreach_vpe_ext_api_reply_msg \ _(INTERFACE_MSG_ID(SW_INTERFACE_DETAILS), sw_interface_details) \ _(INTERFACE_MSG_ID(CREATE_LOOPBACK_INSTANCE_REPLY), create_loopback_instance_reply) \ @@ -739,7 +812,11 @@ static void vpp_base_vpe_init(void) _(L2_MSG_ID(BRIDGE_DOMAIN_DETAILS), bridge_domain_details) \ _(L2_MSG_ID(BVI_CREATE_REPLY), bvi_create_reply) \ _(L2_MSG_ID(BVI_DELETE_REPLY), bvi_delete_reply) \ - _(L2_MSG_ID(BRIDGE_FLAGS_REPLY), bridge_flags_reply) + _(L2_MSG_ID(BRIDGE_FLAGS_REPLY), bridge_flags_reply) \ + _(BOND_MSG_ID(BOND_CREATE_REPLY), bond_create_reply) \ + _(BOND_MSG_ID(BOND_DELETE_REPLY), bond_delete_reply) \ + _(BOND_MSG_ID(BOND_ADD_MEMBER_REPLY), bond_add_member_reply) \ + _(BOND_MSG_ID(BOND_DETACH_MEMBER_REPLY), bond_detach_member_reply) static u16 interface_msg_id_base, ip_msg_id_base, ip_nbr_msg_id_base, lcp_msg_id_base, memclnt_msg_id_base, __plugin_msg_base; static u16 acl_msg_id_base; @@ -864,6 +941,10 @@ static void get_base_msg_id() //SAIVPP_ERROR("DELME: l2_msg_id_base %s msg_base_lookup_name:%s l2_api_version:%08x\n", l2_msg_id_base,msg_base_lookup_name,l2_api_version); //printf("DELME: New change added l2_msg_id_base %s\n", l2_msg_id_base); + msg_base_lookup_name = format (0, "bond_%08x%c", bond_api_version, 0); + bond_msg_id_base = vl_client_get_first_plugin_msg_id ((char *) msg_base_lookup_name); + SAIVPP_WARN("BALA: bond_msg_id_base is %d",bond_msg_id_base); + assert(bond_msg_id_base != (u16) ~0); memclnt_msg_id_base = 0; } @@ -1011,6 +1092,20 @@ static u32 get_swif_idx (vat_main_t *vam, const char *ifname) return ((u32) -1); } +static const char * get_swif_name (vat_main_t *vam, const u32 swif_idx) +{ + hash_pair_t *p; + u8 *name; + u32 value; + + hash_foreach_pair (p, vam->sw_if_index_by_interface_name, ({ + name = (u8 *) (p->key); + value = (u32) p->value[0]; + if (value == swif_idx) return name; + })); + return NULL; +} + static int config_lcp_hostif (vat_main_t *vam, vl_api_interface_index_t if_idx, const char *hostif_name, @@ -2252,3 +2347,160 @@ int set_bridge_domain_flags(uint32_t bd_id, vpp_bd_flags_t flag, bool enable) return ret; } + +int create_bond_interface(uint32_t bond_id, uint32_t mode, uint32_t lb, uint32_t *swif_idx) +{ + vat_main_t *vam = &vat_main; + vl_api_bond_create_t * mp; + int ret; + + + SAIVPP_WARN("Creating bd interface: \n"); + VPP_LOCK(); + + __plugin_msg_base = bond_msg_id_base; + + M (BOND_CREATE, mp); + + mp->id = htonl(bond_id); + mp->mode = htonl(mode); + mp->lb = htonl(lb); + mp->numa_only = false; + mp->use_custom_mac = false; + mp->context = store_ptr(swif_idx); + + S (mp); + + W (ret); + + VPP_UNLOCK(); + + return ret; +} + +int delete_bond_interface(const char *hwif_name) +{ + vat_main_t *vam = &vat_main; + vl_api_bond_delete_t * mp; + int ret; + + + SAIVPP_WARN("Removing bond interface: \n"); + VPP_LOCK(); + + __plugin_msg_base = bond_msg_id_base; + + + M (BOND_DELETE, 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; + } + + S (mp); + + W (ret); + + VPP_UNLOCK(); + + return ret; +} +int create_bond_member(uint32_t bond_sw_if_index, const char *hwif_name, bool is_passive, bool is_long_timeout) +{ + vat_main_t *vam = &vat_main; + vl_api_bond_add_member_t * mp; + int ret; + + + SAIVPP_WARN("Adding member to bond interface: \n"); + VPP_LOCK(); + + __plugin_msg_base = bond_msg_id_base; + + + M (BOND_ADD_MEMBER, 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->bond_sw_if_index = htonl(bond_sw_if_index); + mp->is_passive = is_passive; + mp->is_long_timeout = is_long_timeout; + + S (mp); + + W (ret); + + VPP_UNLOCK(); + + return ret; +} + +const char * vpp_get_swif_name (const u32 swif_idx) +{ + vat_main_t *vam = &vat_main; + return get_swif_name(vam, swif_idx); +} + + +int delete_bond_member(const char * hwif_name) +{ + vat_main_t *vam = &vat_main; + vl_api_bond_detach_member_t *mp; + int ret; + + VPP_LOCK(); + + __plugin_msg_base = bond_msg_id_base; + + M (BOND_DETACH_MEMBER, 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; + } + + S (mp); + + W (ret); + + VPP_UNLOCK(); + + return ret; +} + diff --git a/platform/saivpp/vpplib/vppxlate/SaiVppXlate.h b/platform/saivpp/vpplib/vppxlate/SaiVppXlate.h index 1a2daf5..0dc5220 100644 --- a/platform/saivpp/vpplib/vppxlate/SaiVppXlate.h +++ b/platform/saivpp/vpplib/vppxlate/SaiVppXlate.h @@ -156,7 +156,23 @@ typedef enum { VPP_BD_FLAG_ARP_UFWD = 32, } vpp_bd_flags_t; +typedef enum { + VPP_BOND_API_MODE_ROUND_ROBIN = 1, + VPP_BOND_API_MODE_ACTIVE_BACKUP = 2, + VPP_BOND_API_MODE_XOR = 3, + VPP_BOND_API_MODE_BROADCAST = 4, + VPP_BOND_API_MODE_LACP = 5, +} vpp_bond_mode; + +typedef enum { + VPP_BOND_API_LB_ALGO_L2 = 0, + VPP_BOND_API_LB_ALGO_L34 = 1, + VPP_BOND_API_LB_ALGO_L23 = 2, + VPP_BOND_API_LB_ALGO_RR = 3, + VPP_BOND_API_LB_ALGO_BC = 4, + VPP_BOND_API_LB_ALGO_AB = 5, +} vpp_bond_lb_algo; extern vpp_event_info_t * vpp_ev_dequeue(); extern void vpp_ev_free(vpp_event_info_t *evp); @@ -200,6 +216,11 @@ typedef enum { extern int create_bvi_interface(uint8_t *mac_address, uint32_t instance); extern int delete_bvi_interface(const char *hwif_name); extern int set_bridge_domain_flags(uint32_t bd_id, vpp_bd_flags_t flag, bool enable); + extern int create_bond_interface(uint32_t bond_id, uint32_t mode, uint32_t lb, uint32_t *swif_idx); + extern int delete_bond_interface(const char *hwif_name); + extern int create_bond_member(uint32_t bond_sw_if_index, const char *hwif_name, bool is_passive, bool is_long_timeout); + extern int delete_bond_member(const char * hwif_name); + extern const char * vpp_get_swif_name(const uint32_t swif_idx); #ifdef __cplusplus } From 670c563fcf54560c30598408006bc0f534d306f0 Mon Sep 17 00:00:00 2001 From: bendrapubalareddy Date: Tue, 27 Feb 2024 12:49:54 -0500 Subject: [PATCH 2/4] issue 9: LAG support with 8021q bridging Files Added: LAG-Dot1q-Bridging-Topo.png README.LAG.dot1q.bridging.topo.md Signed-off-by: bendrapubalareddy bala.balareddy@gmail.com --- docs/LAG-Dot1q-Bridging-Topo.png | Bin 0 -> 164516 bytes docs/README.LAG.dot1q.bridging.topo.md | 558 +++++++++++++++++++++++++ 2 files changed, 558 insertions(+) create mode 100644 docs/LAG-Dot1q-Bridging-Topo.png create mode 100644 docs/README.LAG.dot1q.bridging.topo.md diff --git a/docs/LAG-Dot1q-Bridging-Topo.png b/docs/LAG-Dot1q-Bridging-Topo.png new file mode 100644 index 0000000000000000000000000000000000000000..d23424cd52613a20f70e6f1ee4fe615cdbab8737 GIT binary patch literal 164516 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

}Gb_V@X$3ulWINltH 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 literal 0 HcmV?d00001 diff --git a/docs/README.LAG.dot1q.bridging.topo.md b/docs/README.LAG.dot1q.bridging.topo.md new file mode 100644 index 0000000..e95c660 --- /dev/null +++ b/docs/README.LAG.dot1q.bridging.topo.md @@ -0,0 +1,558 @@ +# LAG 8021q bridging Test + +LAG Bridging Simple Test Topology + +SONiC-A connections +``` +Host1-10.0.1.1/24--Ethernet0|-bvi10-10.0.1.10/24-|PortChannel10-trunk1 vlan 10 [members-Ethernet4,5] +Host2-10.0.2.1/24--Ethernet1|-bvi20-10.0.2.20/24-| Ethernet3-trunk vlan20 +Host3-10.0.3.1/24--Ethernet2|------SONiC-A-------| Ethernet3-trunk vlan30 +``` + + +SONiC-B connections +``` + PortChannel10-trunk1 vlan 10 [members-Ethernet2,3] |SONiC-B|Ethernet1 trunk2 vlan 10 + Ethernet0-trunk vlan20] |SONiC-B|Ethernet1 trunk2 vlan 20 + Ethernet0-trunk vlan30 |SONiC-B|Ethernet1 trunk2 vlan 30 +``` + +SONiC-C connections +``` +Ethernet3 trunk2 vlan 10|SONIC-C|Ethernet0-------|Host4-10.0.1.2/24 +Ethernet3 trunk2 vlan 20|SONIC-C|Ethernet1-------|Host5-10.0.2.2/24 +Ethernet3 trunk2 vlan 30|SONiC-C|Ethernet2-------|Host6-10.0.3.2/24 +``` + +Pre-requisites for testing + +Make sure the docker is installed on the Linux system. iproute2 and sudo packages should be installed. + +Load container images +``` +docker load < docker-sonic-vpp.gz +``` + +Check if images are listed +``` +docker images | grep "sonic-vpp\|pause" +``` + +Get the script to create and run the sonic container from the sonic-platform-vpp repo if you have not cloned the repo. +``` +wget https://raw.githubusercontent.com/sonic-net/sonic-platform-vpp/main/start_sonic_vpp.sh +``` +Set the execute bits of the downloaded script file +``` +chmod +x start_sonic_vpp.sh + +``` +Else if you have already cloned the sonic-platform-repo you can copy the script to the local directory and use it. + +On the host create veth interface pairs for vpp and host + +``` +sudo ip link add name veth_ac1 type veth peer name ac1 +sudo ip link add name veth_ac2 type veth peer name ac2 +sudo ip link add name veth_ac3 type veth peer name ac3 +sudo ip link add name veth_ac4 type veth peer name ac4 +sudo ip link add name veth_ac5 type veth peer name ac5 +sudo ip link add name veth_ac6 type veth peer name ac6 +sudo ip link add name veth_pc_member1 type veth peer name pc_member1 +sudo ip link add name veth_pc_member2 type veth peer name pc_member2 +sudo ip link add name veth_trunk1 type veth peer name trunk1 +sudo ip link add name veth_trunk2 type veth peer name trunk2 + +``` + +Create network namespace for end hosts and inject one end of veth pair + +``` +sudo ip netns add host-1.0 +sudo ip netns add host-2.0 +sudo ip netns add host-3.0 +sudo ip netns add host-4.0 +sudo ip netns add host-5.0 +sudo ip netns add host-6.0 +sudo ip link set dev veth_ac1 netns host-1.0 +sudo ip link set dev veth_ac2 netns host-2.0 +sudo ip link set dev veth_ac3 netns host-3.0 +sudo ip link set dev veth_ac4 netns host-4.0 +sudo ip link set dev veth_ac5 netns host-5.0 +sudo ip link set dev veth_ac6 netns host-6.0 +``` + +Configure IP addresses inside the host net namepaces + +``` +sudo ip netns exec host-1.0 bash +ip link set dev veth_ac1 up +ip addr add 10.0.1.1/24 dev veth_ac1 +ip addr add fd12:3456:789a:1::2/64 dev veth_ac1 +ip route add 10.0.2.0/24 via 10.0.1.10 +ip address show +ip route show +exit + +sudo ip netns exec host-2.0 bash +ip link set dev veth_ac2 up +ip addr add 10.0.2.1/24 dev veth_ac2 +ip addr add fd12:3456:789a:2::2/64 dev veth_ac2 +ip route add 10.0.1.0/24 via 10.0.2.20 +ip address show +ip route show +exit + +sudo ip netns exec host-3.0 bash +ip link set dev veth_ac3 up +ip addr add 10.0.3.1/24 dev veth_ac3 +ip addr add fd12:3456:789a:3::2/64 dev veth_ac3 +ip address show +ip route show +exit + +sudo ip netns exec host-4.0 bash +ip link set dev veth_ac4 up +ip addr add 10.0.1.2/24 dev veth_ac4 +ip addr add fd12:3456:789a:1::3/64 dev veth_ac4 +ip route add 10.0.2.0/24 via 10.0.1.10 +ip address show +ip route show +exit + +sudo ip netns exec host-5.0 bash +ip link set dev veth_ac5 up +ip addr add 10.0.2.2/24 dev veth_ac5 +ip addr add fd12:3456:789a:2::3/64 dev veth_ac5 +ip route add 10.0.1.0/24 via 10.0.2.20 +ip address show +ip route show +exit + +sudo ip netns exec host-6.0 bash +ip link set dev veth_ac6 up +ip addr add 10.0.3.2/24 dev veth_ac6 +ip addr add fd12:3456:789a:3::3/64 dev veth_ac6 +ip address show +ip route show +exit +``` + +Now start the sonic container and pass the veth interfaces to sonic-vpp +``` +sudo ./start_sonic_vpp.sh start -n SONIC-A -i ac1,ac2,ac3,trunk1,pc_member1,pc_member2 +``` + +start the second sonic container and pass the veth interfaces to sonic-vpp +``` +sudo ./start_sonic_vpp.sh start -n SONIC-B -i veth_trunk1,veth_trunk2,veth_pc_member1,veth_pc_member2 +``` + +start the third sonic container and pass the veth interfaces to sonic-vpp +``` +sudo ./start_sonic_vpp.sh start -n SONIC-C -i ac4,ac5,ac6,trunk2 +``` + +Get into SONIC-A container and configure vlan and vlan bridging + +SONIC-A: +``` +docker exec -it SONIC-A /bin/bash +show interface status +config interface startup Ethernet0 +config interface startup Ethernet1 +config interface startup Ethernet2 +config interface startup Ethernet3 +config interface startup Ethernet4 +config interface startup Ethernet5 + +config portchannel add PortChannel10 +config portchannel member add PortChannel10 Ethernet4 +config portchannel member add PortChannel10 Ethernet5 + +config vlan add 10 +config vlan member add -u 10 Ethernet0 +config vlan member add 10 PortChannel10 + +config vlan add 20 +config vlan member add -u 20 Ethernet1 +config vlan member add 20 Ethernet3 + +config vlan add 30 +config vlan member add -u 30 Ethernet2 +config vlan member add 30 Ethernet3 + +config interface ip add Vlan10 10.0.1.10/24 +config interface ip add Vlan20 10.0.2.20/24 +``` + +Get into SONIC-B container and configure vlan, vlan bridging + +SONIC-B: +``` +docker exec -it SONIC-B /bin/bash +show interface status +config interface startup Ethernet0 +config interface startup Ethernet1 +config interface startup Ethernet2 +config interface startup Ethernet3 + +config portchannel add PortChannel10 +config portchannel member add PortChannel10 Ethernet2 +config portchannel member add PortChannel10 Ethernet3 + +config vlan add 10 +config vlan member add 10 PortChannel10 +config vlan member add 10 Ethernet1 + +config vlan add 20 +config vlan member add 20 Ethernet0 +config vlan member add 20 Ethernet1 + +config vlan add 30 +config vlan member add 30 Ethernet0 +config vlan member add 30 Ethernet1 +``` + +Get into SONIC-C container and configure vlan, vlan bridging + +SONIC-C: +``` +docker exec -it SONIC-C /bin/bash +show interface status +config interface startup Ethernet0 +config interface startup Ethernet1 +config interface startup Ethernet2 +config interface startup Ethernet3 + +config vlan add 10 +config vlan member add -u 10 Ethernet0 +config vlan member add 10 Ethernet3 + +config vlan add 20 +config vlan member add -u 20 Ethernet1 +config vlan member add 20 Ethernet3 + +config vlan add 30 +config vlan member add -u 30 Ethernet2 +config vlan member add 30 Ethernet3 +``` + +Test the SONiC vlan briding function across 3 VLAN bridge domains + +``` +sudo ip netns exec host-1.0 bash +ping -c5 10.0.1.2 -- same bridge domain +ping -c5 10.0.2.1 -- route to different bridge domain +ping -c5 10.0.2.2 -- route to different bridge domain +ping -c5 10.0.3.1 -- ping fails +ping -c5 10.0.3.2 -- ping fails +exit + +sudo ip netns exec host-2.0 bash +ping -c5 10.0.2.2 -- same bridge domain +ping -c5 10.0.1.1 -- route to different bridge domain +ping -c5 10.0.1.2 -- route to different bridge domain +ping -c5 10.0.3.1 -- ping fails as no routing for this +ping -c5 10.0.3.2 -- ping fail as no routing for this +exit + +sudo ip netns exec host-3.0 bash +ping -c5 10.0.3.2 +ping6 fd12:3456:789a:3::3 -c 5 +ping -c5 10.0.1.1 -- ping fails as no routing for this +ping -c5 10.0.1.2 -- ping fails as no routing for this +ping -c5 10.0.2.1 -- ping fails as no routing for this +ping -c5 10.0.2.2 -- ping fails as no routing for this +exit + +sudo ip netns exec host-4.0 bash +ping -c5 10.0.1.1 +ping -c5 10.0.2.1 -- route to different bridge domain +ping -c5 10.0.2.2 -- route to different bridge domain +ping -c5 10.0.3.1 -- ping fails as no routing for this +ping -c5 10.0.3.2 -- ping fails as no routing for this +exit + +sudo ip netns exec host-5.0 bash +ping -c5 10.0.2.1 +ping -c5 10.0.1.1 -- route to different bridge domain +ping -c5 10.0.1.2 -- route to different bridge domain +ping -c5 10.0.3.1 -- ping fails as no routing for this +ping -c5 10.0.3.2 -- ping fails as no routing for this +exit + +sudo ip netns exec host-6.0 bash +ping -c5 10.0.3.1 +ping6 -c5 fd12:3456:789a:3::3 +ping -c5 10.0.1.1 -- ping fails as no routing for this +ping -c5 10.0.1.2 -- ping fails as no routing for this +ping -c5 10.0.2.1 -- ping fails as no routing for this +ping -c5 10.0.2.2 -- ping fails as no routing for this +exit + +``` + +You should see the ping reachability from host1 to host4, host2 to host5 and host3 to host6. + +Use below command to stop the sonic-vpp containers +``` +sudo ./start_sonic_vpp.sh stop -n sonic-br1 +sudo ./start_sonic_vpp.sh stop -n sonic-br2 +sudo ./start_sonic_vpp.sh stop -n sonic-br3 +``` + +Show command outputs sonic-br1 +``` +show interface status +``` +``` + Interface Lanes Speed MTU FEC Alias Vlan Oper Admin Type Asym PFC + +--------------------------------------------------------------------------------------------------------+ + Ethernet0 25,26,27,28 100G 9100 N/A fortyGigE0/0 routed up down N/A N/A + Ethernet1 29,30,31,32 100G 9100 N/A fortyGigE0/4 routed up down N/A N/A + Ethernet2 33,34,35,36 100G 9100 N/A fortyGigE0/8 routed up down N/A N/A + Ethernet3 37,38,39,40 100G 9100 N/A fortyGigE0/12 routed up down N/A N/A + Ethernet4 45,46,47,48 100G 9100 N/A fortyGigE0/16 routed up down N/A N/A + Ethernet5 41,42,43,44 100G 9100 N/A fortyGigE0/20 routed up down N/A N/A +``` +``` +show vlan brief +``` +``` ++-----------+--------------+---------------+----------------+-------------+ +| VLAN ID | IP Address | Ports | Port Tagging | Proxy ARP | ++===========+==============+===============+================+=============+ +| 10 | 10.0.1.10/24 | Ethernet0 | untagged | disabled | +| | | PortChannel10 | tagged | | ++-----------+--------------+---------------+----------------+-------------+ +| 20 | 10.0.2.20/24 | Ethernet1 | untagged | disabled | +| | | Ethernet3 | tagged | | ++-----------+--------------+---------------+----------------+-------------+ +| 30 | | Ethernet2 | untagged | disabled | +| | | Ethernet3 | tagged | | ++-----------+--------------+---------------+----------------+-------------+ +``` +``` +show vlan config +``` +``` +Name VID Member Mode +------ ----- --------- -------- +Vlan10 10 Ethernet0 untagged +Vlan10 10 PortChannel10 tagged +Vlan20 20 Ethernet1 untagged +Vlan20 20 Ethernet3 tagged +Vlan30 30 Ethernet2 untagged +Vlan30 30 Ethernet3 tagged +``` +``` +vppctl show bridge +``` +``` + BD-ID Index BSN Age(min) Learning U-Forwrd UU-Flood Flooding ARP-Term arp-ufwd Learn-co Learn-li BVI-Intf + 10 1 0 off on on flood on off off 0 16777216 N/A + 20 2 0 off on on flood on off off 0 16777216 N/A + 30 3 0 off on on flood on off off 1 16777216 N/A +``` +``` +vppctl show bridge 10 detail +``` +``` + BD-ID Index BSN Age(min) Learning U-Forwrd UU-Flood Flooding ARP-Term arp-ufwd Learn-co Learn-li BVI-Intf + 10 1 0 off on on flood on on off 0 16777216 bvi10 +span-l2-input l2-input-classify l2-input-feat-arc l2-policer-classify l2-input-acl vpath-input-l2 l2-ip-qos-record l2-input-vtr l2-learn l2-rw l2-fwd l2-flood arp-term-l2bd l2-flood l2-output + + Interface If-idx ISN SHG BVI TxFlood VLAN-Tag-Rewrite + bvi10 19 1 0 * * push-1 dot1q 10 + host-ac1 1 1 0 - * push-1 dot1q 10 + BondEthernet0.10 14 1 0 - * none + + IP4/IP6 to MAC table for ARP Termination +``` +``` +vppctl show bridge 20 detail +``` +``` + BD-ID Index BSN Age(min) Learning U-Forwrd UU-Flood Flooding ARP-Term arp-ufwd Learn-co Learn-li BVI-Intf + 20 2 0 off on on flood on on off 0 16777216 bvi20 +span-l2-input l2-input-classify l2-input-feat-arc l2-policer-classify l2-input-acl vpath-input-l2 l2-ip-qos-record l2-input-vtr l2-learn l2-rw l2-fwd l2-flood arp-term-l2bd l2-flood l2-output + + Interface If-idx ISN SHG BVI TxFlood VLAN-Tag-Rewrite + bvi20 20 1 0 * * push-1 dot1q 20 + host-ac2 2 1 0 - * push-1 dot1q 20 + host-trunk1.20 15 1 0 - * none + + IP4/IP6 to MAC table for ARP Termination +``` +``` +vppctl show bridge 30 detail +``` +``` + BD-ID Index BSN Age(min) Learning U-Forwrd UU-Flood Flooding ARP-Term arp-ufwd Learn-co Learn-li BVI-Intf + 30 3 0 off on on flood on off off 0 16777216 N/A +span-l2-input l2-input-classify l2-input-feat-arc l2-policer-classify l2-input-acl vpath-input-l2 l2-ip-qos-record l2-input-vtr l2-learn l2-rw l2-fwd l2-flood l2-flood l2-output + + Interface If-idx ISN SHG BVI TxFlood VLAN-Tag-Rewrite + host-ac3 3 1 0 - * push-1 dot1q 30 + host-trunk1.30 17 1 0 - * none +``` +``` +vppctl show ip4 neighbors +``` +``` + + Time IP Flags Ethernet Interface + 17703.4524 10.0.1.2 D 52:84:76:96:2c:b7 bvi10 + 17717.2684 10.0.1.1 D 6e:21:47:49:58:49 bvi10 + 17693.9802 10.0.2.1 D da:9c:93:33:db:af bvi20 + 17717.0202 10.0.2.2 D 7e:ef:f5:5c:0f:2a bvi20 +``` +``` +vppctl show interfaces +``` +``` + Name Idx State MTU (L3/IP4/IP6/MPLS) Counter Count +BondEthernet0 13 up 9000/0/0/0 +BondEthernet0.10 14 up 0/0/0/0 +bvi10 19 up 9000/0/0/0 +bvi20 20 up 9000/0/0/0 +host-ac1 1 up 9122/0/0/0 +host-ac2 2 up 9122/0/0/0 +host-ac3 3 up 9122/0/0/0 +host-pc_member1 5 up 9122/0/0/0 +host-pc_member2 6 up 9122/0/0/0 +host-trunk1 4 up 9122/0/0/0 +host-trunk1.20 15 up 0/0/0/0 +host-trunk1.30 17 up 0/0/0/0 +local0 0 down 0/0/0/0 +tap1 8 up 9000/0/0/0 +tap2 7 up 9000/0/0/0 +tap3 9 up 9000/0/0/0 +tap4 10 up 9000/0/0/0 +tap4.20 16 up 0/0/0/0 +tap4.30 18 up 0/0/0/0 +tap5 12 up 9000/0/0/0 +tap6 11 up 9000/0/0/0 +``` +``` +ip addr show +``` +``` +60: Vlan10@Bridge: mtu 9100 qdisc noqueue state UP group default qlen 1000 + link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff + inet 10.0.1.10/24 brd 10.0.1.255 scope global Vlan10 + valid_lft forever preferred_lft forever + inet6 fd12:3456:789a:1::1/64 scope global + valid_lft forever preferred_lft forever + inet6 fe80::42:acff:fe11:5/64 scope link + valid_lft forever preferred_lft forever +61: Vlan20@Bridge: mtu 9100 qdisc noqueue state UP group default qlen 1000 + link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff + inet 10.0.2.20/24 brd 10.0.2.255 scope global Vlan20 + valid_lft forever preferred_lft forever + inet6 fd12:3456:789a:2::1/64 scope global + valid_lft forever preferred_lft forever + inet6 fe80::42:acff:fe11:5/64 scope link + valid_lft forever preferred_lft forever +``` + +``` +vppctl show ip fib +``` +``` + +ipv4-VRF:0, fib_index:0, flow hash:[src dst sport dport proto flowlabel ] epoch:0 flags:none locks:[adjacency:1, default-route:1, ] +0.0.0.0/0 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:1 buckets:1 uRPF:0 to:[0:0]] + [0] [@0]: dpo-drop ip4 +0.0.0.0/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:2 buckets:1 uRPF:1 to:[0:0]] + [0] [@0]: dpo-drop ip4 +10.0.1.0/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:9 buckets:1 uRPF:9 to:[0:0]] + [0] [@0]: dpo-drop ip4 +10.0.1.1/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:17 buckets:1 uRPF:20 to:[5:420]] + [0] [@5]: ipv4 via 10.0.1.1 bvi10: mtu:9000 next:10 flags:[] 6e21474958490242ac1100050800 +10.0.1.2/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:19 buckets:1 uRPF:22 to:[1:84]] + [0] [@5]: ipv4 via 10.0.1.2 bvi10: mtu:9000 next:10 flags:[] 528476962cb70242ac1100050800 +10.0.1.0/24 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:8 buckets:1 uRPF:8 to:[2:168]] + [0] [@4]: ipv4-glean: [src:10.0.1.0/24] bvi10: mtu:9000 next:1 flags:[] ffffffffffff0242ac1100050806 +10.0.1.10/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:11 buckets:1 uRPF:13 to:[0:0]] + [0] [@12]: dpo-receive: 10.0.1.10 on bvi10 +10.0.1.255/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:10 buckets:1 uRPF:11 to:[0:0]] + [0] [@0]: dpo-drop ip4 +10.0.2.0/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:13 buckets:1 uRPF:15 to:[0:0]] + [0] [@0]: dpo-drop ip4 +10.0.2.1/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:18 buckets:1 uRPF:21 to:[1:84]] + [0] [@5]: ipv4 via 10.0.2.1 bvi20: mtu:9000 next:9 flags:[] da9c9333dbaf0242ac1100050800 +10.0.2.2/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:16 buckets:1 uRPF:18 to:[6:504]] + [0] [@5]: ipv4 via 10.0.2.2 bvi20: mtu:9000 next:9 flags:[] 7eeff55c0f2a0242ac1100050800 +10.0.2.0/24 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:12 buckets:1 uRPF:14 to:[2:168]] + [0] [@4]: ipv4-glean: [src:10.0.2.0/24] bvi20: mtu:9000 next:2 flags:[] ffffffffffff0242ac1100050806 +10.0.2.20/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:15 buckets:1 uRPF:19 to:[0:0]] + [0] [@12]: dpo-receive: 10.0.2.20 on bvi20 +10.0.2.255/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:14 buckets:1 uRPF:17 to:[0:0]] + [0] [@0]: dpo-drop ip4 +224.0.0.0/4 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:4 buckets:1 uRPF:3 to:[0:0]] + [0] [@0]: dpo-drop ip4 +240.0.0.0/4 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:3 buckets:1 uRPF:2 to:[0:0]] + [0] [@0]: dpo-drop ip4 +255.255.255.255/32 + unicast-ip4-chain + [@0]: dpo-load-balance: [proto:ip4 index:5 buckets:1 uRPF:4 to:[0:0]] + [0] [@0]: dpo-drop ip4 +``` + +``` +check the connectivity on portchannel interface + +ping 10.0.1.2 +PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data. +64 bytes from 10.0.1.2: icmp_seq=1 ttl=64 time=27.7 ms +64 bytes from 10.0.1.2: icmp_seq=2 ttl=64 time=41.6 ms + +check the packets on portchannel member interfaces + +shutdown one member interface of portchannel, verify the connectivity still fine and verify portchannel member counters +shutdown second member interface of portchannel, verify the connectivity is lost and verify portchannel member counters +bring up second member interface of portchannel back, verify the connectivity is restored and verify portchannel member counters +bring up other member interface of portchannel back, verify the connectivity is restored and verify portchannel member counters +``` +Verification of packet on VPP data plane for vlan tagging +Start the ping and then do show trace + +``` +vppctl +trace add af-packet-input 10 +show trace +``` From d78bdbc8ff8d537d53cebbcf38a6e5f346ff518e Mon Sep 17 00:00:00 2001 From: bendrapubalareddy Date: Tue, 27 Feb 2024 21:06:01 -0500 Subject: [PATCH 3/4] issue 9: LAG feature with bridging support Files Added: docs/HLD/vpp-lag.md Singed-off-by: bendrapubalareddy bala.balareddy@gmail.com --- docs/HLD/vpp-lag.md | 72 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) create mode 100644 docs/HLD/vpp-lag.md diff --git a/docs/HLD/vpp-lag.md b/docs/HLD/vpp-lag.md new file mode 100644 index 0000000..baf4dc9 --- /dev/null +++ b/docs/HLD/vpp-lag.md @@ -0,0 +1,72 @@ +# SONIC VPP LAG Bridging support +Rev v0.1 + +
+
+ +## Table of Contents + +1. [Revisions](#item-1) +2. [Scope](#item-2) +3. [Definitions/Abbreviations](#item-3) +4. [Introduction](#item-4) +5. [LAG and Bridging](#item-5) + +
+
+ + +## Revisions + +| Rev | Date | Author(s) | +|-----|------|-----------| +|v0.1 | 25/02/2024 | Bendrapu Balareddy (Cisco), Sameer Nanajkar (Cisco) | + + +
+
+ + +## Scope +This document describes the high level design of integrating LAG and bridging functionality between SONIC and VPP. It provides + - LAG + - 802.1Q bridging + +
+ + +## Definitions/Abbreviations +**VPP**: Vector Packet Processing (VPP) technology based high performance packet processing stack that can run on commodity CPUs. For more details see [What is VPP](https://wiki.fd.io/view/VPP/What_is_VPP%3F) + +**LAG**: Ling Aggregation Group + + +
+
+ + +## Introduction +LAG functionality is supported in SONiC with port channel interfaces. + + + +![LAG Bridging](../LAG-Dot1q-Bridging-Topo.png) + +SONiC supports port channel interfaces. These interfaces can be configured for layer routing or as members of a vlan + - Access port + config vlan member add -u creates an un tagged bridge port. This will be translated to vpp in two steps + 1. creates a bridge with given vlan id as bridge id if the bridge with given id doesnot exist. + 2. set the port as member of bridge with appropriate tag rewrite + - Trunk port + config vlan member add creates a tagged port bridge port. This will be translated to vpp in three steps + 1. creates a bridge with given vlan id as bridge id if the bridge with given aid does not exist. + 2. vpp trunk port operation is achieved through vlan subinterface. A subinterface is created for this vlan id. Note + that this subinterface is only specific to vpp and does not appear in SONiC control plane data bases. + 3. set the vlan subinterface as bridge port + + +## References + +[SONiC system architecture](https://github.com/sonic-net/SONiC/wiki/Architecture)\ +[What is VPP](https://s3-docs.fd.io/vpp/23.06/) + From 7d3d9ff695e74f6d5bce5261a2f4c916504ccf5b Mon Sep 17 00:00:00 2001 From: bendrapubalareddy Date: Fri, 1 Mar 2024 07:23:58 -0500 Subject: [PATCH 4/4] issue 90: LAG feature support Files modified: modified: docs/HLD/vpp-lag.md modified: docs/README.LAG.dot1q.bridging.topo.md modified: platform/saivpp/vpplib/SwitchStateBase.cpp modified: platform/saivpp/vpplib/SwitchStateBaseFdb.cpp Signed-Off-By: bendrapubalareddy email: bala.balareddy@gmail.com --- docs/HLD/vpp-lag.md | 12 ++++++++++++ docs/README.LAG.dot1q.bridging.topo.md | 18 +++++++++--------- platform/saivpp/vpplib/SwitchStateBase.cpp | 2 -- platform/saivpp/vpplib/SwitchStateBaseFdb.cpp | 17 ++++++----------- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/docs/HLD/vpp-lag.md b/docs/HLD/vpp-lag.md index baf4dc9..1954b68 100644 --- a/docs/HLD/vpp-lag.md +++ b/docs/HLD/vpp-lag.md @@ -47,6 +47,18 @@ This document describes the high level design of integrating LAG and bridging fu ## Introduction LAG functionality is supported in SONiC with port channel interfaces. +VPP port channel supports modes as active-standby , active-active or LACP mode. But SONiC does not have a way program +this through configuration. Hence the portchannel mode as default active-active by giving ROUND_ROBIN value. Similarly +VPP supports different load balancing algorithms for distributing the traffic in active-active mode. But again SONIC +does not support a way to configure any load balancing algorithm, hence it's programmed as BOND_API_LB_ALGO_L2 by default. +If there is any defined requirement in future to use different load balancing algorithm to use by default, it can be +changed accordingly. + +Some parameters the SONIC supports are not supported by VPP. The attributes like min-links for portchannel group, fast-rate +etc are not supported by VPP. + +To enable LACP on VPP, the VPP should be rebuilt with LACP plugin added. Currently sonic-platform-vpp repo uses prebuilt +vpp binary. Hence it needs some changes the way this repo is using the VPP diff --git a/docs/README.LAG.dot1q.bridging.topo.md b/docs/README.LAG.dot1q.bridging.topo.md index e95c660..eec13c4 100644 --- a/docs/README.LAG.dot1q.bridging.topo.md +++ b/docs/README.LAG.dot1q.bridging.topo.md @@ -198,20 +198,20 @@ config interface startup Ethernet2 config interface startup Ethernet3 config portchannel add PortChannel10 +config portchannel member add PortChannel10 Ethernet1 config portchannel member add PortChannel10 Ethernet2 -config portchannel member add PortChannel10 Ethernet3 config vlan add 10 config vlan member add 10 PortChannel10 -config vlan member add 10 Ethernet1 +config vlan member add 10 Ethernet3 config vlan add 20 config vlan member add 20 Ethernet0 -config vlan member add 20 Ethernet1 +config vlan member add 20 Ethernet3 config vlan add 30 config vlan member add 30 Ethernet0 -config vlan member add 30 Ethernet1 +config vlan member add 30 Ethernet3 ``` Get into SONIC-C container and configure vlan, vlan bridging @@ -534,7 +534,7 @@ ipv4-VRF:0, fib_index:0, flow hash:[src dst sport dport proto flowlabel ] epoch: ``` ``` -check the connectivity on portchannel interface +check the connectivity on portchannel interface by starting ping between vlan 10 hosts ping 10.0.1.2 PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data. @@ -543,10 +543,10 @@ PING 10.0.1.2 (10.0.1.2) 56(84) bytes of data. check the packets on portchannel member interfaces -shutdown one member interface of portchannel, verify the connectivity still fine and verify portchannel member counters -shutdown second member interface of portchannel, verify the connectivity is lost and verify portchannel member counters -bring up second member interface of portchannel back, verify the connectivity is restored and verify portchannel member counters -bring up other member interface of portchannel back, verify the connectivity is restored and verify portchannel member counters +1. shutdown one member interface of portchannel, verify the connectivity still fine and verify portchannel member counters +2. shutdown second member interface of portchannel, verify the connectivity is lost and verify portchannel member counters +3. bring up second member interface of portchannel back, verify the connectivity is restored and verify portchannel member counters +4. bring up other member interface of portchannel back, verify the connectivity is restored and verify portchannel member counters ``` Verification of packet on VPP data plane for vlan tagging Start the ping and then do show trace diff --git a/platform/saivpp/vpplib/SwitchStateBase.cpp b/platform/saivpp/vpplib/SwitchStateBase.cpp index dc154e7..1433425 100644 --- a/platform/saivpp/vpplib/SwitchStateBase.cpp +++ b/platform/saivpp/vpplib/SwitchStateBase.cpp @@ -257,14 +257,12 @@ sai_status_t SwitchStateBase::create( { sai_object_id_t object_id; sai_deserialize_object_id(serializedObjectId, object_id); - SWSS_LOG_NOTICE("BALA: create serialized: entry %s objectType %d attr count %d", serializedObjectId.c_str(), object_type, attr_count); return createLag(object_id, switch_id, attr_count, attr_list); } if (object_type == SAI_OBJECT_TYPE_LAG_MEMBER) { sai_object_id_t object_id; sai_deserialize_object_id(serializedObjectId, object_id); - SWSS_LOG_NOTICE("create serialized: entry %s objectType %d attr count %d", serializedObjectId.c_str(), object_type, attr_count); return createLagMember(object_id, switch_id, attr_count, attr_list); } diff --git a/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp b/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp index 1663794..6552949 100644 --- a/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp +++ b/platform/saivpp/vpplib/SwitchStateBaseFdb.cpp @@ -1158,25 +1158,20 @@ sai_status_t SwitchStateBase::vpp_create_lag( _In_ const sai_attribute_t *attr_list) { uint32_t bond_id, mode, lb; - int32_t ret; uint32_t swif_idx = ~0; const char *hw_ifname; SWSS_LOG_ENTER(); - //set mode and lb + //set mode and lb. ONiC config does not have provision to pass mode and load balancing algorithm mode = VPP_BOND_API_MODE_ROUND_ROBIN; + + //if LACP is to be enabled in VPP + //mode = VPP_BOND_API_MODE_LACP; lb = VPP_BOND_API_LB_ALGO_L2; bond_id = ~0; - ret = create_bond_interface(bond_id, mode, lb, &swif_idx); - - if (ret) - { - SWSS_LOG_ERROR("vpp bond interface create failed\n"); - return SAI_STATUS_SUCCESS; - } - - SWSS_LOG_NOTICE("Bond interfae if index:%d\n", swif_idx); + create_bond_interface(bond_id, mode, lb, &swif_idx); + SWSS_LOG_NOTICE("vpp bond interfae created if index:%d\n", swif_idx); //update the lag to bond map m_lag_bond_map[lag_id] = swif_idx; refresh_interfaces_list();