sai_status_t create_port_fn()

in fboss/agent/hw/sai/fake/FakeSaiPort.cpp [21:221]


sai_status_t create_port_fn(
    sai_object_id_t* port_id,
    sai_object_id_t /* switch_id */,
    uint32_t attr_count,
    const sai_attribute_t* attr_list) {
  auto fs = FakeSai::getInstance();
  std::optional<bool> adminState;
  std::vector<uint32_t> lanes;
  std::optional<sai_uint32_t> speed;
  std::optional<sai_port_fec_mode_t> fecMode;
  std::optional<sai_port_internal_loopback_mode_t> internalLoopbackMode;
  std::optional<sai_port_flow_control_mode_t> flowControlMode;
  std::optional<sai_port_media_type_t> mediaType;
  std::optional<sai_vlan_id_t> vlanId;
  std::vector<uint32_t> preemphasis;
  std::vector<sai_object_id_t> ingressMirrorList;
  std::vector<sai_object_id_t> egressMirrorList;
  sai_object_id_t ingressSamplePacket{SAI_NULL_OBJECT_ID};
  sai_object_id_t egressSamplePacket{SAI_NULL_OBJECT_ID};
  std::vector<sai_object_id_t> ingressSampleMirrorList;
  std::vector<sai_object_id_t> egressSampleMirrorList;
  sai_uint32_t mtu{1514};
  sai_object_id_t qosDscpToTcMap{SAI_NULL_OBJECT_ID};
  sai_object_id_t qosTcToQueueMap{SAI_NULL_OBJECT_ID};
  bool disableTtlDecrement{false};
  sai_port_interface_type_t interface_type{SAI_PORT_INTERFACE_TYPE_NONE};
  bool txEnable{true};
  std::optional<sai_object_id_t> ingressMacsecAcl;
  std::optional<sai_object_id_t> egressMacsecAcl;
  std::optional<uint16_t> systemPortId;
  std::optional<sai_port_ptp_mode_t> ptpMode;
  for (int i = 0; i < attr_count; ++i) {
    switch (attr_list[i].id) {
      case SAI_PORT_ATTR_ADMIN_STATE:
        adminState = attr_list[i].value.booldata;
        break;
      case SAI_PORT_ATTR_HW_LANE_LIST: {
        for (int j = 0; j < attr_list[i].value.u32list.count; ++j) {
          lanes.push_back(attr_list[i].value.u32list.list[j]);
        }
      } break;
      case SAI_PORT_ATTR_SPEED:
        speed = attr_list[i].value.u32;
        break;
      case SAI_PORT_ATTR_FEC_MODE:
        fecMode = static_cast<sai_port_fec_mode_t>(attr_list[i].value.u32);
        break;
      case SAI_PORT_ATTR_INTERNAL_LOOPBACK_MODE:
        internalLoopbackMode = static_cast<sai_port_internal_loopback_mode_t>(
            attr_list[i].value.u32);
        break;
      case SAI_PORT_ATTR_MEDIA_TYPE:
        mediaType = static_cast<sai_port_media_type_t>(attr_list[i].value.s32);
        break;
      case SAI_PORT_ATTR_GLOBAL_FLOW_CONTROL_MODE:
        flowControlMode =
            static_cast<sai_port_flow_control_mode_t>(attr_list[i].value.s32);
        break;
      case SAI_PORT_ATTR_PORT_VLAN_ID:
        vlanId = attr_list[i].value.u16;
        break;
      case SAI_PORT_ATTR_SERDES_PREEMPHASIS: {
        for (int j = 0; j < attr_list[i].value.u32list.count; ++j) {
          preemphasis.push_back(attr_list[i].value.u32list.list[j]);
        }
      } break;
      case SAI_PORT_ATTR_MTU:
        mtu = attr_list[i].value.u32;
        break;
      case SAI_PORT_ATTR_QOS_DSCP_TO_TC_MAP:
        qosDscpToTcMap = attr_list[i].value.oid;
        break;
      case SAI_PORT_ATTR_QOS_TC_TO_QUEUE_MAP:
        qosTcToQueueMap = attr_list[i].value.oid;
        break;
      case SAI_PORT_ATTR_DISABLE_DECREMENT_TTL:
        disableTtlDecrement = attr_list[i].value.booldata;
        break;
      case SAI_PORT_ATTR_INTERFACE_TYPE:
        interface_type =
            static_cast<sai_port_interface_type_t>(attr_list[i].value.s32);
        break;
      case SAI_PORT_ATTR_PKT_TX_ENABLE:
        txEnable = attr_list[i].value.booldata;
        break;
      case SAI_PORT_ATTR_INGRESS_MIRROR_SESSION: {
        for (int j = 0; j < attr_list[i].value.objlist.count; ++j) {
          ingressMirrorList.push_back(attr_list[i].value.objlist.list[j]);
        }
      } break;
      case SAI_PORT_ATTR_EGRESS_MIRROR_SESSION: {
        for (int j = 0; j < attr_list[i].value.objlist.count; ++j) {
          egressMirrorList.push_back(attr_list[i].value.objlist.list[j]);
        }
      } break;
      case SAI_PORT_ATTR_INGRESS_SAMPLEPACKET_ENABLE:
        ingressSamplePacket = attr_list[i].value.oid;
        break;
      case SAI_PORT_ATTR_EGRESS_SAMPLEPACKET_ENABLE:
        egressSamplePacket = attr_list[i].value.oid;
        break;
#if SAI_API_VERSION >= SAI_VERSION(1, 7, 0)
      case SAI_PORT_ATTR_INGRESS_SAMPLE_MIRROR_SESSION: {
        for (int j = 0; j < attr_list[i].value.objlist.count; ++j) {
          ingressMirrorList.push_back(attr_list[i].value.objlist.list[j]);
        }
      } break;
      case SAI_PORT_ATTR_EGRESS_SAMPLE_MIRROR_SESSION: {
        for (int j = 0; j < attr_list[i].value.objlist.count; ++j) {
          egressMirrorList.push_back(attr_list[i].value.objlist.list[j]);
        }
      } break;
#endif
      case SAI_PORT_ATTR_INGRESS_MACSEC_ACL:
        ingressMacsecAcl = attr_list[i].value.oid;
        break;
      case SAI_PORT_ATTR_EGRESS_MACSEC_ACL:
        egressMacsecAcl = attr_list[i].value.oid;
        break;
      case SAI_PORT_ATTR_EXT_FAKE_SYSTEM_PORT_ID:
        systemPortId = attr_list[i].value.u16;
        break;
      case SAI_PORT_ATTR_PTP_MODE:
        ptpMode = static_cast<sai_port_ptp_mode_t>(attr_list[i].value.s32);
        break;
      default:
        return SAI_STATUS_INVALID_PARAMETER;
    }
  }
  if (lanes.empty() || !speed) {
    return SAI_STATUS_INVALID_PARAMETER;
  }
  *port_id = fs->portManager.create(lanes, speed.value());
  auto& port = fs->portManager.get(*port_id);
  if (adminState) {
    port.adminState = adminState.value();
  }
  if (fecMode.has_value()) {
    port.fecMode = fecMode.value();
  }
  if (internalLoopbackMode.has_value()) {
    port.internalLoopbackMode = internalLoopbackMode.value();
  }
  if (vlanId.has_value()) {
    port.vlanId = vlanId.value();
  }
  if (mediaType.has_value()) {
    port.mediaType = mediaType.value();
  }
  if (vlanId.has_value()) {
    port.vlanId = vlanId.value();
  }
  if (preemphasis.size()) {
    port.preemphasis = preemphasis;
  }
  if (ingressMirrorList.size()) {
    port.ingressMirrorList = ingressMirrorList;
  }
  if (egressMirrorList.size()) {
    port.egressMirrorList = egressMirrorList;
  }
  if (ingressSampleMirrorList.size()) {
    port.ingressSampleMirrorList = ingressSampleMirrorList;
  }
  if (egressSampleMirrorList.size()) {
    port.egressSampleMirrorList = egressSampleMirrorList;
  }
  if (ingressMacsecAcl.has_value()) {
    port.ingressMacsecAcl = ingressMacsecAcl.value();
  }
  if (egressMacsecAcl.has_value()) {
    port.egressMacsecAcl = egressMacsecAcl.value();
  }
  if (systemPortId.has_value()) {
    port.systemPortId = systemPortId.value();
  }
  if (ptpMode.has_value()) {
    port.ptpMode = ptpMode.value();
  }
  port.mtu = mtu;
  port.qosDscpToTcMap = qosDscpToTcMap;
  port.qosTcToQueueMap = qosTcToQueueMap;
  port.ingressSamplePacket = ingressSamplePacket;
  port.egressSamplePacket = egressSamplePacket;
  port.disableTtlDecrement = disableTtlDecrement;
  port.txEnable = txEnable;
  // TODO: Use number of queues by querying SAI_SWITCH_ATTR_NUMBER_OF_QUEUES
  for (uint8_t queueId = 0; queueId < 7; queueId++) {
    auto saiQueueId = fs->queueManager.create(
        SAI_QUEUE_TYPE_UNICAST, *port_id, queueId, *port_id);
    port.queueIdList.push_back(saiQueueId);
    if (queueId == 6) {
      // Create queue 6 for multicast also.
      saiQueueId = fs->queueManager.create(
          SAI_QUEUE_TYPE_MULTICAST, *port_id, queueId, *port_id);
      port.queueIdList.push_back(saiQueueId);
    }
  }
  port.interface_type = interface_type;
  return SAI_STATUS_SUCCESS;
}