static cps_api_return_code_t _write_function(void * context, cps_api_transaction_params_t * param,size_t ix) {
    GILLock gil;

    cps_api_object_t obj = cps_api_object_list_get(param->change_list,ix);
    if (obj==NULL) return cps_api_ret_code_ERR;

    cps_api_object_t prev = cps_api_object_list_get(param->prev,ix);
    if(prev==NULL) {
        prev = cps_api_object_list_create_obj_and_append(param->prev);
    }
    if (prev==NULL) return cps_api_ret_code_ERR;

    cps_api_operation_types_t op = cps_api_object_type_operation(cps_api_object_key(obj));

    PyObject *p = PyDict_New();
    PyRef dict(p);

    py_cps_util_set_item_to_dict(p,"change",cps_obj_to_dict(obj));
    py_cps_util_set_item_to_dict(p,"previous",cps_obj_to_dict(prev));

    static const std::map<int,std::string> trans = {
            {cps_api_oper_DELETE,"delete" },
            {cps_api_oper_CREATE,"create"},
            {cps_api_oper_SET, "set"},
            {cps_api_oper_ACTION,"rpc"}
    };

    py_cps_util_set_item_to_dict(p,"operation",PyString_FromString(trans.at(op).c_str()));

    py_callbacks_t *cb = (py_callbacks_t*)context;
    PyObject *res = cb->execute("transaction",p);

    if (res==NULL || !PyBool_Check(res) || (Py_False==(res))) {
        return cps_api_ret_code_ERR;
    }
    PyRef ret(res);

    PyObject *ch = PyDict_GetItemString(p,"change");
    if (ch==NULL) return cps_api_ret_code_ERR;

    cps_api_object_t o = dict_to_cps_obj(ch);
    cps_api_object_guard og(o);
    if(og.valid()) {
        cps_api_object_clone(obj,og.get());
    }

    PyObject *pr = PyDict_GetItemString(p,"previous");
    if (pr==NULL) return cps_api_ret_code_ERR;
    og.set(dict_to_cps_obj(pr));
    if (og.valid()) {
        cps_api_object_clone(prev,og.get());
    }
    return cps_api_ret_code_OK;
}
extern "C" cps_api_return_code_t cps_api_get_objs(cps_api_object_t filt, cps_api_object_list_t obj_list,
        size_t retry_count, size_t ms_delay_between) {

    cps_api_return_code_t rc;
    cps_api_get_params_t get_req;

    if ((rc=cps_api_get_request_init(&get_req))!=cps_api_ret_code_OK) return rc;

    cps_api_get_request_guard rg(&get_req);

    cps_api_object_t obj = cps_api_object_list_create_obj_and_append(get_req.filters);
    if (obj==nullptr) return cps_api_ret_code_ERR;
    if (!cps_api_object_clone(obj,filt)) return cps_api_ret_code_ERR;

    if (ms_delay_between==0) ms_delay_between = BASIC_WAIT_TIME;
    ms_delay_between = MILLI_TO_MICRO(ms_delay_between);

    cps_api_object_list_t _tmp_lst = get_req.list;
    get_req.list = obj_list;

    bool inf = retry_count==0;
    while (inf || (retry_count >0) ) {
        rc = cps_api_get(&get_req);
        if (rc==cps_api_ret_code_OK) break;
        if (!inf) --retry_count;
        std_usleep(ms_delay_between);
    }
    get_req.list = _tmp_lst;
    return rc;
}
static t_std_error dn_nas_get_phy_media_default_setting(PLATFORM_MEDIA_TYPE_t media_type, cps_api_object_t obj)
{
    cps_api_get_params_t gp;
    cps_api_get_request_init(&gp);
    cps_api_get_request_guard rg(&gp);

    cps_api_object_t media_obj = cps_api_object_list_create_obj_and_append(gp.filters);
    t_std_error rc = STD_ERR_MK(e_std_err_INTERFACE, e_std_err_code_FAIL, 0);

    do {
        if (!cps_api_key_from_attr_with_qual(cps_api_object_key(media_obj),
                                BASE_MEDIA_MEDIA_INFO_OBJ, cps_api_qualifier_OBSERVED)) {
            break;
        }
        cps_api_set_key_data_uint(media_obj, BASE_MEDIA_MEDIA_INFO_MEDIA_TYPE, &media_type, sizeof(media_type));
        cps_api_object_attr_add_u32(media_obj, BASE_MEDIA_MEDIA_INFO_MEDIA_TYPE, media_type);
        if (cps_api_get(&gp) != cps_api_ret_code_OK)
            break;

        if (0 == cps_api_object_list_size(gp.list))
            break;

        media_obj = cps_api_object_list_get(gp.list,0);
        if (!cps_api_object_clone(obj, media_obj)) {
            break;
        }
        rc = STD_ERR_OK;
    } while(0);
    return rc;
}
extern "C" t_std_error nas_os_get_interface_obj(hal_ifindex_t ifix,cps_api_object_t obj) {
    cps_api_object_list_guard lg(cps_api_object_list_create());
    if (lg.get()==NULL) return STD_ERR(NAS_OS,FAIL,0);

    if (_get_interfaces(lg.get(),ifix,false)!=cps_api_ret_code_OK) {
        return STD_ERR(NAS_OS,FAIL,0);
    }

    cps_api_object_t ret = cps_api_object_list_get(lg.get(),0);
    if (ret==nullptr) {
        return STD_ERR(NAS_OS,FAIL,0);
    }
    cps_api_object_clone(obj,ret);
    return STD_ERR_OK;
}
extern "C" cps_api_return_code_t cps_api_object_stats(cps_api_key_t *key, cps_api_object_t stats_obj) {
    cps_api_return_code_t rc = cps_api_ret_code_ERR;

    cps_api_channel_t handle = -1;

    if (key==nullptr || cps_api_key_get_len(key)==0) {
        std_socket_address_t addr;
        cps_api_ns_get_address(&addr);

        int sock;
        t_std_error _rc = std_sock_connect(&addr,&sock);
        if (_rc!=STD_ERR_OK) {
            return rc;
        }
        handle = sock;
    } else {
        if (!cps_api_get_handle(*key,handle)) {
            char buff[CPS_API_KEY_STR_MAX];
            EV_LOG(ERR,DSAPI,0,"NS","Failed to find owner for %s",
                    cps_api_key_print(key,buff,sizeof(buff)-1));
            return cps_api_ret_code_NO_SERVICE;
        }
    }
    if (handle==-1) {
        EV_LOG(ERR,DSAPI,0,"NS-STATS","No connection to the NS for stats.");
        return rc;
    }
    do {
        if (!cps_api_send_header(handle,cps_api_msg_o_STATS,0)) {
            break;
        }
        size_t len;
        uint32_t op=0;
        if (!cps_api_receive_header(handle,op,len)) break;
        if (op!=cps_api_msg_o_STATS) break;

        cps_api_object_guard og (cps_api_receive_object(handle,len));
        if(!og.valid()) return false;

        if (!cps_api_object_clone(stats_obj,og.get())) {
            break;
        }
        rc = cps_api_ret_code_OK;
    } while (0);
    cps_api_disconnect_owner(handle);
    return rc;
}
cps_api_return_code_t cps_api_set_node_group(cps_api_node_group_t *group) {

    cps_api_object_guard og(cps_api_object_create());

    cps_api_key_from_attr_with_qual(cps_api_object_key(og.get()),CPS_NODE_GROUP, cps_api_qualifier_TARGET);

    cps_api_object_attr_add(og.get(),CPS_NODE_GROUP_NAME,group->id,strlen(group->id)+1);

    for ( size_t ix = 0; ix < group->addr_len; ++ix ) {
        cps_api_attr_id_t _ip[]= {CPS_NODE_GROUP_NODE,ix,CPS_NODE_GROUP_NODE_IP};
        cps_api_object_e_add(og.get(),_ip,sizeof(_ip)/sizeof(*_ip),cps_api_object_ATTR_T_BIN,
                             group->addrs[ix].addr,strlen(group->addrs[ix].addr)+1);
        cps_api_attr_id_t _alias[]= {CPS_NODE_GROUP_NODE,ix,CPS_NODE_GROUP_NODE_NAME};
        cps_api_object_e_add(og.get(),_alias,sizeof(_alias)/sizeof(*_alias),cps_api_object_ATTR_T_BIN,
                             group->addrs[ix].node_name,strlen(group->addrs[ix].node_name)+1);
    }

    cps_api_object_attr_add(og.get(),CPS_NODE_GROUP_TYPE,&group->data_type,sizeof(group->data_type));

    cps_db::connection_request b(cps_db::ProcessDBCache(),DEFAULT_REDIS_ADDR);
    if (!b.valid()) {
        return cps_api_ret_code_ERR;
    }
    cps_api_object_guard tmp(cps_api_object_create());

    if (!cps_api_object_clone(tmp.get(),og.get())) {
        return cps_api_ret_code_ERR;
    }

    bool changed = false;
    if (cps_db::get_object(b.get(),tmp.get())) {
        changed = true;
    }

    (void)changed;
    if (!cps_db::store_object(b.get(),og.get())) {
        return cps_api_ret_code_ERR;
    }

    if(group->data_type == cps_api_node_data_1_PLUS_1_REDUNDENCY) {
        return cps_api_create_global_instance(group);
    }
    ///TODO send out changed...

    return cps_api_ret_code_OK;
}
cps_api_return_code_t cps_api_process_commit_request(cps_api_transaction_params_t *param, size_t ix) {
    cps_api_return_code_t rc = cps_api_ret_code_ERR;

    cps_api_object_t obj = cps_api_object_list_get(param->change_list,ix);
    cps_api_object_t pre = cps_api_object_list_get(param->prev,ix);
    if (obj==NULL) {
        EV_LOG(ERR,DSAPI,0,"CPS IPC","No Commit Object");
        return rc;
    }

    cps_api_channel_t handle;
    cps_api_key_t *key = cps_api_object_key(obj);

    char buff[CPS_API_KEY_STR_MAX];
    EV_LOG(TRACE,DSAPI,0, "CPS IPC", "Object for commit request: %s ",
                                    cps_api_key_name_print(key, buff, sizeof(buff)));


    if (!cps_api_get_handle(*key,handle)) {
        EV_LOG(ERR,DSAPI,0,"CPS IPC","No Service");
        return cps_api_ret_code_NO_SERVICE;
    }


    rc = cps_api_ret_code_ERR;

    fd_set rset;
    FD_ZERO(&rset);
    FD_SET(handle,&rset);

    do {
        if (!cps_api_send_one_object(handle,cps_api_msg_o_COMMIT_CHANGE,obj)) {
            EV_LOG(ERR,DSAPI,0,"CPS IPC","Could not send COMMIT CHANGE ");
            break;
        }

        if (!cps_api_send_one_object(handle,cps_api_msg_o_COMMIT_PREV,pre)) {
            EV_LOG(ERR,DSAPI,0,"CPS IPC","Could not send COMMIT PREV ");
            break;
        }


        uint32_t op;
        size_t len;
        if (param->timeout > 0) {
            if ((rc=cps_api_timeout_wait(handle,&rset,param->timeout,"CPS-OP-TR"))!=cps_api_ret_code_OK) {
                EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction Response timed out ");
                break;
            }
        }
        rc = cps_api_ret_code_ERR;

        if (!cps_api_receive_header(handle,op,len)) {
            EV_LOG(ERR,DSAPI,0,"CPS IPC","Failed to read the receive header ");
            break;
        }


        if (op == cps_api_msg_o_COMMIT_OBJECT) {
            cps_api_object_guard og(cps_api_receive_object(handle,len));
            if (!og.valid()) {
                EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction response missing cur object..");
                break;
            }
            cps_api_object_clone(obj,og.get());

            if (!cps_api_receive_header(handle,op,len)) {
                EV_LOG(ERR,DSAPI,0,"CPS IPC","Failed to read the receive header for prev object ");
                break;
            }

            if (op!=cps_api_msg_o_COMMIT_OBJECT) {
                EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction response header incorrect for prev object" );
                break;
            }

            if (len>0) {
                cps_api_object_guard og(cps_api_receive_object(handle,len));
                if (!og.valid()) {
                    EV_LOG(ERR,DSAPI,0,"CPS IPC","Transaction response missing resp object..");
                    break;
                }
                obj = cps_api_object_list_get(param->prev,ix);

                if (obj==NULL) { //if there was no previous object passed by client override
                    if (cps_api_object_list_append(param->prev,og.get())) {
                        og.release();
                        rc = cps_api_ret_code_OK;
                    }
                } else {
                    //take the previous provided by the client if the key is valid
                    //assume that the data is valid too
                    if (cps_api_key_get_len(cps_api_object_key(og.get()))>0) {
                        cps_api_object_clone(obj,og.get());
                    }
                    rc = cps_api_ret_code_OK;
                }
            }
        }
        if (op == cps_api_msg_o_RETURN_CODE) {
            if (!cps_api_receive_data(handle,&rc,sizeof(rc))) break;
        }
    } while (0);

    cps_api_disconnect_owner(handle);

    return rc;
}
static cps_api_return_code_t nas_qos_cps_api_map_create(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj,
                                nas_qos_map_type_t map_type)
{
    uint_t switch_id;
    nas_obj_id_t map_id = 0;
    nas_qos_map_entry_key_t key;
    cps_api_return_code_t rc = cps_api_ret_code_OK;

    // check the request is on Map level or Entry level
    bool is_map_entry;
    if ((rc = qos_map_key_check(obj, map_type, &is_map_entry)) != cps_api_ret_code_OK) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Key error");
        return rc;
    }

    if (is_map_entry) {
        if ((rc = qos_map_entry_get_key(obj, map_type, switch_id, map_id, key)) != cps_api_ret_code_OK)
            return rc;

    }
    else {
        if ((rc = qos_map_get_switch_id(obj, map_type, switch_id)) != cps_api_ret_code_OK)
            return rc;

        // while creating map id, do not accept map-entry attributes.
        // Map-entry needs to be created separately.
        if (qos_map_entry_attr_is_set(obj, map_type)) {
            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                "Inner list map entries must be created separately after map id is created\n");
            return NAS_QOS_E_INCONSISTENT;
        }
    }

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    try {
        if (!is_map_entry) {
            // Map id create

            nas_qos_map map(p_switch, map_type);

            map_id = p_switch->alloc_map_id();

            map.set_map_id(map_id);

            map.commit_create(sav_obj? false: true);

            p_switch->add_map(map);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Created new map %u\n",
                         map.get_map_id());

            // update obj with new map-id attr and key
            nas_attr_id_t map_id_obj_id = qos_map_map_id_obj_id(map_type);
            cps_api_set_key_data(obj,
                    map_id_obj_id,
                    cps_api_object_ATTR_T_U64,
                    &map_id, sizeof(uint64_t));

            // save for rollback if caller requests it.
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return cps_api_ret_code_ERR;
                }
                cps_api_object_clone(tmp_obj, obj);
            }
        }
        else {
            // Map entry create
            nas_qos_map * p_map = p_switch->get_map(map_id);
            if (p_map == NULL) {
                EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                        "NAS map id %lu is not found", map_id);
                return NAS_QOS_E_FAIL;
            }

            if (p_map->get_type() != map_type) {
                EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                        "NAS map id %lu has mismatched type: %d vs expected %d",
                        map_id, p_map->get_type(), map_type);
                return NAS_QOS_E_INCONSISTENT;
            }

            nas_qos_map_entry entry(p_switch, map_id, map_type, key);

            if ((rc = nas_qos_cps_parse_attr(obj, entry)) != cps_api_ret_code_OK)
                return rc;

            //push a create to NPUs
            entry.commit_create(sav_obj? false: true);

            p_map->add_map_entry(key, entry);

            EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                    "Created new map entry with key %u\n",
                         key.any);

            // save for rollback if caller requests it.
            if (sav_obj) {
                cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
                if (tmp_obj == NULL) {
                    return cps_api_ret_code_ERR;
                }
                cps_api_object_clone(tmp_obj, obj);
            }
        }
    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS %s Create error code: %d ",
                    (is_map_entry? "Map Entry": "Map"),
                    e.err_code);
        if (!is_map_entry && map_id)
            p_switch->release_map_id(map_id);

        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS %s Create Unexpected error code",
                    (is_map_entry? "Map Entry": "Map"));
        if (!is_map_entry && map_id)
            p_switch->release_map_id(map_id);

        return NAS_QOS_E_FAIL;
    }

    return cps_api_ret_code_OK;
}
static cps_api_return_code_t nas_qos_cps_api_scheduler_group_create(
                                cps_api_object_t obj,
                                cps_api_object_list_t sav_obj)
{
#ifndef R_1_0_DISABLE_SG_CREATE
    nas_obj_id_t scheduler_group_id = 0;

    cps_api_object_attr_t switch_attr = cps_api_get_key_data(obj, BASE_QOS_SCHEDULER_GROUP_SWITCH_ID);
    if (switch_attr == NULL ) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", " switch id not specified in the message\n");
        return NAS_QOS_E_FAIL;
    }

    uint_t switch_id = cps_api_object_attr_data_u32(switch_attr);

    nas_qos_switch *p_switch = nas_qos_get_switch(switch_id);
    if (p_switch == NULL)
        return NAS_QOS_E_FAIL;

    nas_qos_scheduler_group scheduler_group(p_switch);

    if (nas_qos_cps_parse_attr(obj, scheduler_group) != cps_api_ret_code_OK)
        return NAS_QOS_E_FAIL;

    if (scheduler_group.get_level() == 0 &&
        scheduler_group.dirty_attr_list().contains(BASE_QOS_SCHEDULER_GROUP_SCHEDULER_PROFILE_ID)) {
        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS",
                " Scheduler Group Level 0 node does not accept Scheduler Profile ID; "
                " Use Port Egress Object to configure Scheduler Profile!\n");
        return NAS_QOS_E_FAIL;
    }

    try {
        scheduler_group_id = p_switch->alloc_scheduler_group_id();

        scheduler_group.set_scheduler_group_id(scheduler_group_id);

        scheduler_group.commit_create(sav_obj? false: true);

        p_switch->add_scheduler_group(scheduler_group);

        EV_LOG_TRACE(ev_log_t_QOS, 3, "NAS-QOS", "Created new scheduler_group %u\n",
                     scheduler_group.get_scheduler_group_id());

        // update obj with new scheduler_group-id key
        cps_api_set_key_data(obj, BASE_QOS_SCHEDULER_GROUP_ID,
                cps_api_object_ATTR_T_U64,
                &scheduler_group_id, sizeof(uint64_t));

        // save for rollback if caller requests it.
        if (sav_obj) {
            cps_api_object_t tmp_obj = cps_api_object_list_create_obj_and_append(sav_obj);
            if (!tmp_obj) {
                return NAS_QOS_E_FAIL;
            }
            cps_api_object_clone(tmp_obj, obj);

        }

    } catch (nas::base_exception e) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Create error code: %d ",
                    e.err_code);
        if (scheduler_group_id)
            p_switch->release_scheduler_group_id(scheduler_group_id);

        return NAS_QOS_E_FAIL;

    } catch (...) {
        EV_LOG_TRACE(ev_log_t_QOS, ev_log_s_MAJOR, "QOS",
                    "NAS SCHEDULER_GROUP Create Unexpected error code");
        if (scheduler_group_id)
            p_switch->release_scheduler_group_id(scheduler_group_id);

        return NAS_QOS_E_FAIL;
    }

#endif
    return cps_api_ret_code_OK;
}
示例#10
0
int main() {

    if (!netlinl_test()) {
        exit(1);
    }

    cps_api_linux_init();
    {
        cps_api_get_params_t gr;
        cps_api_get_request_init(&gr);

        cps_api_key_t if_key;
        cps_api_int_if_key_create(&if_key,false,0,0);
        gr.key_count = 1;
        gr.keys = &if_key;
        //ignore failures since all we want is to fill up the get request
        if (cps_api_get(&gr) != cps_api_ret_code_OK) {
            printf("cps_api_get() failed\n");
        }

        cps_api_get_request_close(&gr);
    }
    cps_api_get_params_t gp;

    if (cps_api_get_request_init(&gp)!=cps_api_ret_code_OK) {
        exit(1);
    }

    cps_api_key_t key;
    cps_api_int_if_key_create(&key,false,0,0);

    gp.key_count = 1;
    gp.keys = &key;

    cps_api_transaction_params_t tr;

    if (cps_api_transaction_init(&tr)!=cps_api_ret_code_OK) {
        cps_api_get_request_close(&gp);
        return -1;
    }

    if (cps_api_get(&gp)==cps_api_ret_code_OK) {
        size_t ix = 0;
        size_t mx = cps_api_object_list_size(gp.list);
        char buff[1024];
        for ( ; ix < mx ; ++ix ) {
            cps_api_object_t obj = cps_api_object_list_get(gp.list,ix);
            printf("Obj %d -> %s\n",(int)ix,cps_api_object_to_string(obj,buff,sizeof(buff)));

            cps_api_object_t clone = cps_api_object_create();
            if (!cps_api_object_clone(clone,obj)) {
                printf("Clone Failed %d -> %s\n",(int)ix,cps_api_object_to_string(clone,buff,sizeof(buff)));
            }
            else {
                printf("Clone %d -> %s\n",(int)ix,cps_api_object_to_string(clone,buff,sizeof(buff)));
            }
            cps_api_set(&tr,clone);
        }
    }
    cps_api_get_request_close(&gp);

    if (cps_api_commit(&tr)!=cps_api_ret_code_OK) {
        return -1;
    }
    cps_api_transaction_close(&tr);


    return 0;
}