diff --git a/vslib/src/sai_vs_hostintf.cpp b/vslib/src/sai_vs_hostintf.cpp index 93d158126141..766ce747efc4 100644 --- a/vslib/src/sai_vs_hostintf.cpp +++ b/vslib/src/sai_vs_hostintf.cpp @@ -901,7 +901,9 @@ void send_port_up_notification( int ifup( _In_ const char *dev, - _In_ sai_object_id_t port_id) + _In_ sai_object_id_t port_id, + _In_ bool up, + _In_ bool explicitNotification) { SWSS_LOG_ENTER(); @@ -931,7 +933,7 @@ int ifup( return err; } - if (ifr.ifr_flags & IFF_UP) + if (up && explicitNotification && (ifr.ifr_flags & IFF_UP)) { close(s); @@ -946,7 +948,14 @@ int ifup( return 0; } - ifr.ifr_flags |= IFF_UP; + if (up) + { + ifr.ifr_flags |= IFF_UP; + } + else + { + ifr.ifr_flags &= ~IFF_UP; + } err = ioctl(s, SIOCSIFFLAGS, &ifr); @@ -1094,8 +1103,11 @@ void hostif_info_t::veth2tap_fun() if (size < 0) { - SWSS_LOG_ERROR("failed to read from socket fd %d, errno(%d): %s", - packet_socket, errno, strerror(errno)); + if (errno != ENETDOWN) + { + SWSS_LOG_ERROR("failed to read from socket fd %d, errno(%d): %s", + packet_socket, errno, strerror(errno)); + } continue; } @@ -1215,8 +1227,11 @@ void hostif_info_t::tap2veth_fun() if (write(packet_socket, buffer, (int)size) < 0) { - SWSS_LOG_ERROR("failed to write to socket fd %d, errno(%d): %s", - packet_socket, errno, strerror(errno)); + if (errno != ENETDOWN) + { + SWSS_LOG_ERROR("failed to write to socket fd %d, errno(%d): %s", + packet_socket, errno, strerror(errno)); + } continue; } @@ -1319,7 +1334,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(), port_id)) + if (ifup(vethname.c_str(), port_id, true, true)) { SWSS_LOG_ERROR("ifup failed on %s", vethname.c_str()); @@ -1681,6 +1696,37 @@ sai_status_t vs_create_hostif( &vs_create_hostif_int); } +sai_status_t vs_set_admin_state( + _In_ sai_object_id_t portId, + _In_ bool up) +{ + SWSS_LOG_ENTER(); + + // find corresponding host if interface and bring it down ! + for (auto& kvp: hostif_info_map) + { + auto tapname = kvp.first; + + if (kvp.second->portid == portId) + { + std::string vethname = vs_get_veth_name(tapname, portId); + + if (ifup(vethname.c_str(), portId, up, false)) + { + SWSS_LOG_ERROR("if admin %s failed on %s failed: %s", (up ? "UP" : "DOWN"), vethname.c_str(), strerror(errno)); + + return SAI_STATUS_FAILURE; + } + + SWSS_LOG_NOTICE("if admin %s success on %s", (up ? "UP" : "DOWN"), vethname.c_str()); + + break; + } + } + + return SAI_STATUS_SUCCESS; +} + // TODO set must also be supported when we change operational status up/down // and probably also generate notification then diff --git a/vslib/src/sai_vs_port.cpp b/vslib/src/sai_vs_port.cpp index 65b043f3dae5..5a24a9b9fa31 100644 --- a/vslib/src/sai_vs_port.cpp +++ b/vslib/src/sai_vs_port.cpp @@ -517,6 +517,10 @@ sai_status_t vs_remove_port( return SAI_STATUS_SUCCESS; } +sai_status_t vs_set_admin_state( + _In_ sai_object_id_t port_id, + _In_ bool up); + sai_status_t vs_set_port_attribute( _In_ sai_object_id_t port_id, _In_ const sai_attribute_t *attr) @@ -524,6 +528,13 @@ sai_status_t vs_set_port_attribute( MUTEX(); SWSS_LOG_ENTER(); + if (attr && attr->id == SAI_PORT_ATTR_ADMIN_STATE) + { + bool up = attr->value.booldata; + + vs_set_admin_state(port_id, up); + } + std::string cmd; // Special handling for the sampling attribute modification