zoukankan      html  css  js  c++  java
  • SAI:Switch Abstraction Interface

    https://github.com/opencomputeproject/SAI

    The Switch Abstraction Interface defines the API to provide a vendor-independent way of controlling forwarding elements, such as a switching ASIC, an NPU or a software switch in a uniform manner.

    简单理解,SAI是对转发芯片进行一层功能抽象,SDK为每个模块(如VLAN/PORT/FDB等)提供一组函数集,API通过函数集调用SDK接口从而实现转发面的配置管理;另外实现了一套事件处理回调处理。

    不足之处:

    1)转发芯片功能抽象不稳定,导致接口或参数频繁变化

    2)无协议报文处理模块

    3)事件处理功能不完整

    4)函数集居然不是注册方式

    1、main(saiserver.cpp)

    1)创建转发芯片:create_switch

    sai_api_query(SAI_API_SWITCH, (void**)&sai_switch_api);

    attr[0].id = SAI_SWITCH_ATTR_INIT_SWITCH;
    attr[0].value.booldata = true;

    attr[1].id = SAI_SWITCH_ATTR_SWITCH_STATE_CHANGE_NOTIFY;
    attr[1].value.ptr = reinterpret_cast<sai_pointer_t>(&on_switch_state_change); //注册事件处理函数

    attr[2].id = SAI_SWITCH_ATTR_SHUTDOWN_REQUEST_NOTIFY;
    attr[2].value.ptr = reinterpret_cast<sai_pointer_t>(&on_shutdown_request);

    attr[3].id = SAI_SWITCH_ATTR_FDB_EVENT_NOTIFY;
    attr[3].value.ptr = reinterpret_cast<sai_pointer_t>(&on_fdb_event);

    attr[4].id = SAI_SWITCH_ATTR_PORT_STATE_CHANGE_NOTIFY;
    attr[4].value.ptr = reinterpret_cast<sai_pointer_t>(&on_port_state_change);

    attr[5].id = SAI_SWITCH_ATTR_PACKET_EVENT_NOTIFY;
    attr[5].value.ptr = reinterpret_cast<sai_pointer_t>(&on_packet_event);

    sai_switch_api->create_switch(&gSwitchId, attrSz, attr);

    2)stub版本的创建芯片

    const sai_switch_api_t switch_api = {
    stub_initialize_switch,
    stub_shutdown_switch,
    stub_connect_switch,
    stub_disconnect_switch,
    stub_set_switch_attribute,
    stub_get_switch_attribute,
    };

    sai_status_t stub_initialize_switch(_In_ sai_switch_profile_id_t profile_id,
    _In_reads_z_(SAI_MAX_HARDWARE_ID_LEN) char * switch_hardware_id,
    _In_reads_opt_z_(SAI_MAX_FIRMWARE_PATH_NAME_LEN) char* firmware_path_name,
    _In_ sai_switch_notification_t * switch_notifications)

    memcpy(&g_notification_callbacks, switch_notifications, sizeof(g_notification_callbacks));

    db_init_vlan();
    db_init_next_hop_group();

    3)创建rpc线程

    start_sai_thrift_rpc_server(SWITCH_SAI_THRIFT_RPC_SERVER_PORT);

    2、rpc线程

    static void * switch_sai_thrift_rpc_server_thread(void *arg) {
    int port = *(int *) arg;
    shared_ptr<switch_sai_rpcHandler> handler(new switch_sai_rpcHandler());
    shared_ptr<TProcessor> processor(new switch_sai_rpcProcessor(handler));
    shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
    shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
    shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());

    TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
    server.serve();
    return 0;
    }

    3、功能处理,以创建vlan为例  //class switch_sai_rpcHandler

    1) sai_thrift_object_id_t sai_thrift_create_vlan(const std_sai_thrift_attr_vctr_t &thrift_attr_list) 

    sai_api_query(SAI_API_VLAN, reinterpret_cast<void**>(&vlan_api));  //获取vlan模块函数集
    sai_thrift_parse_vlan_attributes(thrift_attr_list, attr_list);
    vlan_api->create_vlan(&vlanObjId, gSwitchId, attr_size, attr_list);  //创建vlan

    2)sai_api_query

    sai_status_t sai_api_query(_In_ sai_api_t sai_api_id, _Out_ void** api_method_table)
    case SAI_API_VLAN:
    *(const sai_vlan_api_t**)api_method_table = &vlan_api;   //各芯片提供各个模块的函数集
    return SAI_STATUS_SUCCESS;
    case SAI_API_ROUTE:
    *(const sai_route_api_t**)api_method_table = &route_api;
    return SAI_STATUS_SUCCESS;

    3)stub or sdk

    const sai_vlan_api_t vlan_api = {
    stub_create_vlan,
    stub_remove_vlan,
    stub_set_vlan_attribute,
    stub_get_vlan_attribute,
    stub_add_ports_to_vlan,
    stub_remove_ports_from_vlan,
    stub_remove_all_vlans,
    stub_get_vlan_stats,
    NULL
    };

    4、获取函数集,sai_api_query

    switch (sai_api_id) {
    case SAI_API_SWITCH:
    *(const sai_switch_api_t**)api_method_table = &switch_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_PORT:
    *(const sai_port_api_t**)api_method_table = &port_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_FDB:
    *(const sai_fdb_api_t**)api_method_table = &fdb_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_VLAN:
    *(const sai_vlan_api_t**)api_method_table = &vlan_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_VIRTUAL_ROUTER:
    *(const sai_virtual_router_api_t**)api_method_table = &router_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_ROUTE:
    *(const sai_route_api_t**)api_method_table = &route_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_NEXT_HOP:
    *(const sai_next_hop_api_t**)api_method_table = &next_hop_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_NEXT_HOP_GROUP:
    *(const sai_next_hop_group_api_t**)api_method_table = &next_hop_group_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_ROUTER_INTERFACE:
    *(const sai_router_interface_api_t**)api_method_table = &router_interface_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_NEIGHBOR:
    *(const sai_neighbor_api_t**)api_method_table = &neighbor_api;
    return SAI_STATUS_SUCCESS;

    case SAI_API_QOS_MAPS:
    /* TODO : implement */
    return SAI_STATUS_NOT_IMPLEMENTED;

    case SAI_API_ACL:
    /* TODO : implement */
    return SAI_STATUS_NOT_IMPLEMENTED;

    case SAI_API_HOST_INTERFACE:
    *(const sai_hostif_api_t**)api_method_table = &host_interface_api;
    return SAI_STATUS_SUCCESS;

    模块划分:

    typedef enum _sai_api_t
    {
    SAI_API_UNSPECIFIED = 0, /**< unspecified API */
    SAI_API_SWITCH = 1, /**< sai_switch_api_t */
    SAI_API_PORT = 2, /**< sai_port_api_t */
    SAI_API_FDB = 3, /**< sai_fdb_api_t */
    SAI_API_VLAN = 4, /**< sai_vlan_api_t */
    SAI_API_VIRTUAL_ROUTER = 5, /**< sai_virtual_router_api_t */
    SAI_API_ROUTE = 6, /**< sai_route_api_t */
    SAI_API_NEXT_HOP = 7, /**< sai_next_hop_api_t */
    SAI_API_NEXT_HOP_GROUP = 8, /**< sai_next_hop_group_api_t */
    SAI_API_ROUTER_INTERFACE = 9, /**< sai_router_interface_api_t */
    SAI_API_NEIGHBOR = 10, /**< sai_neighbor_api_t */
    SAI_API_ACL = 11, /**< sai_acl_api_t */
    SAI_API_HOSTIF = 12, /**< sai_hostif_api_t */
    SAI_API_MIRROR = 13, /**< sai_mirror_api_t */
    SAI_API_SAMPLEPACKET = 14, /**< sai_samplepacket_api_t */
    SAI_API_STP = 15, /**< sai_stp_api_t */
    SAI_API_LAG = 16, /**< sai_lag_api_t */
    SAI_API_POLICER = 17, /**< sai_policer_api_t */
    SAI_API_WRED = 18, /**< sai_wred_api_t */
    SAI_API_QOS_MAP = 19, /**< sai_qos_map_api_t */
    SAI_API_QUEUE = 20, /**< sai_queue_api_t */
    SAI_API_SCHEDULER = 21, /**< sai_scheduler_api_t */
    SAI_API_SCHEDULER_GROUP = 22, /**< sai_scheduler_group_api_t */
    SAI_API_BUFFER = 23, /**< sai_buffer_api_t */
    SAI_API_HASH = 24, /**< sai_hash_api_t */
    SAI_API_UDF = 25, /**< sai_udf_api_t */
    SAI_API_TUNNEL = 26, /**< sai_tunnel_api_t */
    SAI_API_L2MC = 27, /**< sai_l2mc_api_t */
    SAI_API_IPMC = 28, /**< sai_ipmc_api_t */
    SAI_API_RPF_GROUP = 29, /**< sai_rpf_group_api_t */
    SAI_API_L2MC_GROUP = 30, /**< sai_l2mc_group_api_t */
    SAI_API_IPMC_GROUP = 31, /**< sai_ipmc_group_api_t */
    SAI_API_MCAST_FDB = 32, /**< sai_mcast_fdb_api_t */
    SAI_API_BRIDGE = 33, /**< sai_bridge_api_t */
    SAI_API_TAM = 34, /**< sai_tam_api_t */
    SAI_API_SEGMENTROUTE = 35, /**< sai_segmentroute_api_t */
    SAI_API_MPLS = 36, /**< sai_mpls_api_t */
    SAI_API_UBURST = 37, /**< sai_uburst_api_t */
    SAI_API_MAX = 38, /**< total number of APIs */
    } sai_api_t;

  • 相关阅读:
    Signals & Slots(Qt5)
    Build Qt5 Source 配置Qt5
    关于android studio从2.3升级到3.0以上可能会遇到的问题
    Error:Unexpected lock protocol found in lock file. Expected 3, found 49.
    关于浏览器自动展示用户名、密码等输入框的解决办法
    mysql 使用zip包进行安装以及服务启动后立即关闭问题
    fiddler抓包小技巧之自动保存抓包数据(可根据需求过滤)
    mysql binlog日志解析
    SharePoint 2010 Development Stack
    不仅仅是土豆
  • 原文地址:https://www.cnblogs.com/heimafeitian/p/9653275.html
Copyright © 2011-2022 走看看