From 533749062f638f74ebc09c4bd0a5162b2c575564 Mon Sep 17 00:00:00 2001 From: Kamil Cudnik Date: Fri, 22 Nov 2019 03:57:09 +0100 Subject: [PATCH] Send port status notification when creating hostif interface (#535) --- lib/src/sai_redis_interfacequery.cpp | 6 +-- syncd/syncd.cpp | 2 +- vslib/inc/sai_vs_state.h | 7 +++ vslib/src/sai_vs_hostintf.cpp | 76 +++++++++++++++++++++++++++- 4 files changed, 85 insertions(+), 6 deletions(-) diff --git a/lib/src/sai_redis_interfacequery.cpp b/lib/src/sai_redis_interfacequery.cpp index 04407bc61ab8..8a8e1c71a3d8 100644 --- a/lib/src/sai_redis_interfacequery.cpp +++ b/lib/src/sai_redis_interfacequery.cpp @@ -351,7 +351,7 @@ sai_status_t sai_query_attribute_enum_values_capability( recordLine("Q|attribute_enum_values_capability|SAI_STATUS_FAILURE"); } - SWSS_LOG_ERROR("Invalid response from syncd: expected 2 values, received %d", values.size()); + SWSS_LOG_ERROR("Invalid response from syncd: expected 2 values, received %zu", values.size()); return SAI_STATUS_FAILURE; } @@ -375,7 +375,7 @@ sai_status_t sai_query_attribute_enum_values_capability( { if (num_capabilities != i + 1) { - SWSS_LOG_WARN("Query returned less attributes than expected: expected %d, recieved %d"); + SWSS_LOG_WARN("Query returned less attributes than expected: expected %d, recieved %d", num_capabilities, i+1); } break; @@ -492,7 +492,7 @@ sai_status_t sai_object_type_get_availability( recordLine("Q|object_type_get_availability|SAI_STATUS_FAILURE"); } - SWSS_LOG_ERROR("Invalid response from syncd: expected 1 value, received %d", values.size()); + SWSS_LOG_ERROR("Invalid response from syncd: expected 1 value, received %zu", values.size()); return SAI_STATUS_FAILURE; } diff --git a/syncd/syncd.cpp b/syncd/syncd.cpp index 08b9b7596a61..7535c87d1605 100644 --- a/syncd/syncd.cpp +++ b/syncd/syncd.cpp @@ -2883,7 +2883,7 @@ sai_status_t processAttrEnumValuesCapabilityQuery( if (values.size() != 3) { - SWSS_LOG_ERROR("Invalid input: expected 3 arguments, received %d", values.size()); + SWSS_LOG_ERROR("Invalid input: expected 3 arguments, received %zu", values.size()); getResponse->set(sai_serialize_status(SAI_STATUS_INVALID_PARAMETER), {}, attrEnumValuesCapabilityResponse); return SAI_STATUS_INVALID_PARAMETER; } diff --git a/vslib/inc/sai_vs_state.h b/vslib/inc/sai_vs_state.h index 94e7edeecdcc..0e11b66251b3 100644 --- a/vslib/inc/sai_vs_state.h +++ b/vslib/inc/sai_vs_state.h @@ -328,4 +328,11 @@ void processFdbInfo( _In_ const fdb_info_t &fi, _In_ sai_fdb_event_t fdb_event); +void update_port_oper_status( + _In_ sai_object_id_t port_id, + _In_ sai_port_oper_status_t port_oper_status); + +std::shared_ptr vs_get_switch_state( + _In_ sai_object_id_t switch_id); + #endif // __SAI_VS_STATE__ diff --git a/vslib/src/sai_vs_hostintf.cpp b/vslib/src/sai_vs_hostintf.cpp index 679e2e53245a..df16035319ff 100644 --- a/vslib/src/sai_vs_hostintf.cpp +++ b/vslib/src/sai_vs_hostintf.cpp @@ -791,7 +791,71 @@ int vs_set_dev_mac_address( return err; } -int ifup(const char *dev) +void send_port_up_notification( + _In_ sai_object_id_t port_id) +{ + SWSS_LOG_ENTER(); + + sai_object_id_t switch_id = sai_switch_id_query(port_id); + + if (switch_id == SAI_NULL_OBJECT_ID) + { + SWSS_LOG_ERROR("failed to get switch OID from port id %s", + sai_serialize_object_id(port_id).c_str()); + return; + } + + std::shared_ptr sw = vs_get_switch_state(switch_id); + + if (sw == nullptr) + { + SWSS_LOG_ERROR("failed to get switch state for switch id %s", + sai_serialize_object_id(switch_id).c_str()); + return; + } + + sai_attribute_t attr; + + attr.id = SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY; + + if (vs_switch_api.get_switch_attribute(switch_id, 1, &attr) != SAI_STATUS_SUCCESS) + { + SWSS_LOG_ERROR("failed to get SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY for switch %s", + sai_serialize_object_id(switch_id).c_str()); + return; + } + + sai_port_state_change_notification_fn callback = + (sai_port_state_change_notification_fn)attr.value.ptr; + + if (callback == NULL) + { + SWSS_LOG_INFO("SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY callback is NULL"); + return; + } + + sai_port_oper_status_notification_t data; + + data.port_id = port_id; + data.port_state = SAI_PORT_OPER_STATUS_UP; + + attr.id = SAI_PORT_ATTR_OPER_STATUS; + + update_port_oper_status(port_id, data.port_state); + + SWSS_LOG_NOTICE("explicitly send SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY for port %s: %s (port was UP)", + sai_serialize_object_id(data.port_id).c_str(), + sai_serialize_port_oper_status(data.port_state).c_str()); + + // NOTE this callback should be executed from separate non blocking thread + + if (callback) + callback(1, &data); +} + +int ifup( + _In_ const char *dev, + _In_ sai_object_id_t port_id) { SWSS_LOG_ENTER(); @@ -825,6 +889,14 @@ int ifup(const char *dev) { close(s); + // interface status didn't changed, we need to send manual notification + // that interface status is UP but that notification would need to be + // sent after actual interface creation, since user may receive that + // notification before hostif create function will actually return, + // this can happen when syncd will be operating in synchronous mode + + send_port_up_notification(port_id); + return 0; } @@ -1201,7 +1273,7 @@ bool hostif_create_tap_veth_forwarding( SWSS_LOG_INFO("interface index = %d %s\n", sock_address.sll_ifindex, vethname.c_str()); - if (ifup(vethname.c_str())) + if (ifup(vethname.c_str(), port_id)) { SWSS_LOG_ERROR("ifup failed on %s", vethname.c_str());