Beispiel #1
0
/********************************************************************
* FUNCTION mgr_cap_set_caps
*
* Initialize the NETCONF manager capabilities
*
* TEMP !!! JUST SET EVERYTHING, WILL REALLY GET FROM MGR STARTUP
*
* INPUTS:
*    none
* RETURNS:
*    NO_ERR if all goes well
*********************************************************************/
status_t 
    mgr_cap_set_caps (void)
{
    val_value_t *oldcaps, *newcaps;
    cap_list_t *oldmycaps,*newmycaps;
    xmlns_id_t  nc_id;
    status_t  res;

    res = NO_ERR;
    newcaps = NULL;
    nc_id = xmlns_nc_id();
    oldcaps = mgr_caps;
    oldmycaps = my_mgr_caps;

    /* get a new cap_list */
    newmycaps = cap_new_caplist();
    if (!newmycaps) {
        res = ERR_INTERNAL_MEM;
    }

    /* get a new val_value_t cap list for manager <hello> messages */
    if (res == NO_ERR) {
        newcaps = xml_val_new_struct(NCX_EL_CAPABILITIES, nc_id);
        if (!newcaps) {
            res = ERR_INTERNAL_MEM;
        }
    }

    /* add capability for NETCONF version 1.0 support */
    if (res == NO_ERR) {
        res = cap_add_std(newmycaps, CAP_STDID_V1);
        if (res == NO_ERR) {
            res = cap_add_stdval(newcaps, CAP_STDID_V1);
        }
    }

    /* check the return value */
    if (res != NO_ERR) {
        /* toss the new, put back the old */
        cap_free_caplist(newmycaps);
        val_free_value(newcaps);
        my_mgr_caps = oldmycaps;
        mgr_caps = oldcaps;
    } else {
        /* toss the old, install the new */
        if (oldmycaps) {
            cap_free_caplist(oldmycaps);
        }
        if (oldcaps) {
            val_free_value(oldcaps);
        }
        my_mgr_caps = newmycaps;
        mgr_caps = newcaps;
    }   

    return res;

} /* mgr_cap_set_caps */
Beispiel #2
0
/********************************************************************
* FUNCTION mgr_cap_get_ses_capsval
*
* Get the NETCONF manager capabilities ain val_value_t format
* for a specific session, v2 supports base1.0 and/or base1.1
* INPUTS:
*    scb == session control block to use
* RETURNS:
*    MALLOCED pointer to the manager caps list to use
*    and then discard with val_free_value
*********************************************************************/
val_value_t * 
    mgr_cap_get_ses_capsval (ses_cb_t *scb)
{
    val_value_t *newcaps;
    xmlns_id_t  nc_id;
    status_t    res;

    nc_id = xmlns_nc_id();
    res = NO_ERR;

    /* get a new val_value_t cap list for manager <hello> messages */
    newcaps = xml_val_new_struct(NCX_EL_CAPABILITIES, nc_id);
    if (newcaps == NULL) {
        return NULL;
    }

    /* add capability for NETCONF version 1.0 support */
    if (ses_protocol_requested(scb, NCX_PROTO_NETCONF10)) {
        res = cap_add_stdval(newcaps, CAP_STDID_V1);
    }
    /* add capability for NETCONF version 1.1 support */
    if (res == NO_ERR &&
        ses_protocol_requested(scb, NCX_PROTO_NETCONF11)) {
        res = cap_add_stdval(newcaps, CAP_STDID_V11);
    }

    /* check the return value */
    if (res != NO_ERR) {
        val_free_value(newcaps);
        newcaps = NULL;
    }   

    return newcaps;;


} /* mgr_cap_get_ses_capsval */
Beispiel #3
0
/********************************************************************
* FUNCTION send_lock_pdu_to_server
* 
* Send a <lock> or <unlock> operation to the server
*
* INPUTS:
*   server_cb == server control block to use
*   lockcb == lock control block to use within server_cb
*   islock == TRUE for lock; FALSE for unlock
*
* RETURNS:
*    status
*********************************************************************/
static status_t
    send_lock_pdu_to_server (server_cb_t *server_cb,
                            lock_cb_t *lockcb,
                            boolean islock)
{
    obj_template_t        *rpc, *input;
    mgr_rpc_req_t         *req;
    val_value_t           *reqdata, *targetval, *parmval;
    ses_cb_t              *scb;
    status_t               res;
    xmlns_id_t             obj_nsid;

    req = NULL;
    reqdata = NULL;
    res = NO_ERR;

    if (LOGDEBUG) {
        log_debug("\nSending <%s> request",
                  (islock) ? NCX_EL_LOCK : NCX_EL_UNLOCK);
    }

    if (islock) {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_LOCK);
    } else {
        rpc = ncx_find_object(get_netconf_mod(server_cb), 
                              NCX_EL_UNLOCK);
    }
    if (!rpc) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    obj_nsid = obj_get_nsid(rpc);

    /* get the 'input' section container */
    input = obj_find_child(rpc, NULL, YANG_K_INPUT);
    if (!input) {
        return SET_ERROR(ERR_NCX_DEF_NOT_FOUND);
    }

    /* construct a method + parameter tree */
    reqdata = xml_val_new_struct(obj_get_name(rpc), obj_nsid);
    if (!reqdata) {
        log_error("\nError allocating a new RPC request");
        return ERR_INTERNAL_MEM;
    }

    /* set the [un]lock/input/target node XML namespace */
    targetval = xml_val_new_struct(NCX_EL_TARGET, obj_nsid);
    if (!targetval) {
        log_error("\nError allocating a new RPC request");
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(targetval, reqdata);
    }

    parmval = xml_val_new_flag(lockcb->config_name,
                               obj_nsid);
    if (!parmval) {
        val_free_value(reqdata);
        return ERR_INTERNAL_MEM;
    } else {
        val_add_child(parmval, targetval);
    }

    scb = mgr_ses_get_scb(server_cb->mysid);
    if (!scb) {
        res = SET_ERROR(ERR_INTERNAL_PTR);
    } else {
        req = mgr_rpc_new_request(scb);
        if (!req) {
            res = ERR_INTERNAL_MEM;
            log_error("\nError allocating a new RPC request");
        } else {
            req->data = reqdata;
            req->rpc = rpc;
            req->timeout = server_cb->timeout;
        }
    }
        
    /* if all OK, send the RPC request */
    if (res == NO_ERR) {
        if (LOGDEBUG2) {
            log_debug2("\nabout to send RPC request with reqdata:");
            val_dump_value_max(reqdata, 
                               0,
                               server_cb->defindent,
                               DUMP_VAL_LOG,
                               server_cb->display_mode,
                               FALSE,
                               FALSE);
        }

        /* the request will be stored if this returns NO_ERR */
        res = mgr_rpc_send_request(scb, req, yangcli_reply_handler);
        if (res == NO_ERR) {
            if (islock) {
                lockcb->lock_state = LOCK_STATE_REQUEST_SENT;
            } else {
                lockcb->lock_state = LOCK_STATE_RELEASE_SENT;
            }
            (void)uptime(&lockcb->last_msg_time);
            server_cb->locks_cur_cfg = lockcb->config_id;
        }
    }

    /* cleanup and set next state */
    if (res != NO_ERR) {
        if (req) {
            mgr_rpc_free_request(req);
        } else if (reqdata) {
            val_free_value(reqdata);
        }
    } else {
        server_cb->state = MGR_IO_ST_CONN_RPYWAIT;
    }

    return res;

} /* send_lock_pdu_to_server */
Beispiel #4
0
/********************************************************************
* FUNCTION agt_cap_set_caps
*
* Initialize the NETCONF agent capabilities
*
* INPUTS:
*    agttarg == the target of edit-config for this agent
*    agtstart == the type of startup configuration for this agent
*    defstyle == default with-defaults style for the entire agent
*
* RETURNS:
*    NO_ERR if all goes well
*********************************************************************/
status_t 
    agt_cap_set_caps (ncx_agttarg_t  agttarg,
                      ncx_agtstart_t agtstart,
                      const xmlChar *defstyle)
{
    xmlns_id_t nc_id = xmlns_nc_id();
    status_t res = NO_ERR;
    val_value_t *newcaps = NULL;
    val_value_t *oldcaps = agt_caps;
    cap_list_t *oldmycaps = my_agt_caps;
    const agt_profile_t *agt_profile = agt_get_profile();

    /* get a new cap_list */
    cap_list_t *newmycaps = cap_new_caplist();
    if (!newmycaps) {
        res = ERR_INTERNAL_MEM;
    }

    /* get a new val_value_t cap list for agent <hello> messages */
    if (res == NO_ERR) {
        newcaps = xml_val_new_struct(NCX_EL_CAPABILITIES, nc_id);
        if (!newcaps) {
            res = ERR_INTERNAL_MEM;
        }
    }

    /* add capability for NETCONF version 1.0 and/or 1.1 support */
    if (res == NO_ERR) {
        if (ncx_protocol_enabled(NCX_PROTO_NETCONF10)) {
            res = cap_add_std(newmycaps, CAP_STDID_V1);
            if (res == NO_ERR) {
                res = cap_add_stdval(newcaps, CAP_STDID_V1);
            }
        }
        if (ncx_protocol_enabled(NCX_PROTO_NETCONF11)) {
            res = cap_add_std(newmycaps, CAP_STDID_V11);
            if (res == NO_ERR) {
                res = cap_add_stdval(newcaps, CAP_STDID_V11);
            }
        }
    }

    if (res == NO_ERR) {
        /* set the capabilities based on the native target */
        switch (agttarg) {
        case NCX_AGT_TARG_RUNNING:
            res = cap_add_std(newmycaps, CAP_STDID_WRITE_RUNNING);
            if (res == NO_ERR) {
                res = cap_add_stdval(newcaps, CAP_STDID_WRITE_RUNNING);
            }
            break;
        case NCX_AGT_TARG_CANDIDATE:
            res = cap_add_std(newmycaps, CAP_STDID_CANDIDATE);
            if (res == NO_ERR) {
                res = cap_add_stdval(newcaps, CAP_STDID_CANDIDATE);
            }

            if (res == NO_ERR) {
                if (ncx_protocol_enabled(NCX_PROTO_NETCONF10)) {
                    res = cap_add_std(newmycaps, 
                                      CAP_STDID_CONF_COMMIT);
                    if (res == NO_ERR) {
                        res = cap_add_stdval(newcaps, 
                                             CAP_STDID_CONF_COMMIT);
                    }
                }
                if (ncx_protocol_enabled(NCX_PROTO_NETCONF11)) {
                    res = cap_add_std(newmycaps, 
                                      CAP_STDID_CONF_COMMIT11);
                    if (res == NO_ERR) {
                        res = cap_add_stdval(newcaps, 
                                             CAP_STDID_CONF_COMMIT11);
                    }
                }
            }
            break;
        default:
            res = SET_ERROR(ERR_INTERNAL_VAL);
            break;
        }
    }

    if (res == NO_ERR) {
        /* set the rollback-on-error capability */
        res = cap_add_std(newmycaps, CAP_STDID_ROLLBACK_ERR);
        if (res == NO_ERR) {
            res = cap_add_stdval(newcaps, CAP_STDID_ROLLBACK_ERR);
        }
    }

    if (res == NO_ERR) {
        if (agt_profile->agt_usevalidate) {
            /* set the validate capability */
            if (ncx_protocol_enabled(NCX_PROTO_NETCONF10)) {
                res = cap_add_std(newmycaps, CAP_STDID_VALIDATE);
                if (res == NO_ERR) {
                    res = cap_add_stdval(newcaps, CAP_STDID_VALIDATE);
                }
            }
            if (ncx_protocol_enabled(NCX_PROTO_NETCONF11)) {
                res = cap_add_std(newmycaps, CAP_STDID_VALIDATE11);
                if (res == NO_ERR) {
                    res = cap_add_stdval(newcaps, CAP_STDID_VALIDATE11);
                }
            }
        }
    }

    /* check the startup type for distinct-startup capability */
    if (res == NO_ERR) {
        if (agtstart==NCX_AGT_START_DISTINCT) {
            res = cap_add_std(newmycaps, CAP_STDID_STARTUP);
            if (res == NO_ERR) {
                res = cap_add_stdval(newcaps, CAP_STDID_STARTUP);
            }
        }
    }

    /* set the url capability */
    if (res == NO_ERR) {
        if (agt_profile->agt_useurl) {
            res = cap_add_url(newmycaps, AGT_URL_SCHEME_LIST);
            if (res == NO_ERR) {
                res = cap_add_urlval(newcaps, AGT_URL_SCHEME_LIST);
            }
        }
    }

    /* set the xpath capability */
    if (res == NO_ERR) {
        res = cap_add_std(newmycaps, CAP_STDID_XPATH);
        if (res == NO_ERR) {
            res = cap_add_stdval(newcaps, CAP_STDID_XPATH);
        }
    }

    /* set the notification capability if enabled */
    if (agt_profile->agt_use_notifications) {
        if (res == NO_ERR) {
            res = cap_add_std(newmycaps, CAP_STDID_NOTIFICATION);
            if (res == NO_ERR) {
                res = cap_add_stdval(newcaps, CAP_STDID_NOTIFICATION);
            }
        }

        /* set the interleave capability */
        if (res == NO_ERR) {
            res = cap_add_std(newmycaps, CAP_STDID_INTERLEAVE);
            if (res == NO_ERR) {
                res = cap_add_stdval(newcaps, CAP_STDID_INTERLEAVE);
            }
        }
    }

    /* set the partial-lock capability */
    if (res == NO_ERR) {
        res = cap_add_std(newmycaps, CAP_STDID_PARTIAL_LOCK);
        if (res == NO_ERR) {
            res = cap_add_stdval(newcaps, 
                                 CAP_STDID_PARTIAL_LOCK);
        }
    }

    /* set the with-defaults capability */
    if (res == NO_ERR) {
        res = cap_add_withdef(newmycaps, defstyle);
        if (res == NO_ERR) {
            res = cap_add_withdefval(newcaps, defstyle);
        }
    }

    /* check the return value */
    if (res != NO_ERR) {
        /* toss the new, put back the old */
        cap_free_caplist(newmycaps);
        val_free_value(newcaps);
        my_agt_caps = oldmycaps;
        agt_caps = oldcaps;
    } else {
        /* toss the old, install the new */
        if (oldmycaps) {
            cap_free_caplist(oldmycaps);
        }
        if (oldcaps) {
            val_free_value(oldcaps);
        }
        my_agt_caps = newmycaps;
        agt_caps = newcaps;
    }   

    return res;

} /* agt_cap_set_caps */
/********************************************************************
 * FUNCTION do_while (local RPC)
 * 
 * Handle the while command; start a new loopcb context
 *
 * while expr='xpath-str' [docroot=$foo]
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the show command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *
 * RETURNS:
 *   status
 *********************************************************************/
status_t
    do_while (server_cb_t *server_cb,
              obj_template_t *rpc,
              const xmlChar *line,
              uint32  len)
{
    val_value_t        *valset, *docroot, *expr, *dummydoc, *maxloops;
    xpath_pcb_t        *pcb;
    status_t            res;
    uint32              maxloopsval;

    docroot = NULL;
    expr = NULL;
    pcb = NULL;
    dummydoc = NULL;
    res = NO_ERR;
    maxloopsval = YANGCLI_DEF_MAXLOOPS;

    valset = get_valset(server_cb, rpc, &line[len], &res);
    if (valset == NULL) {
        return res;
    }
    if (res != NO_ERR) {
        val_free_value(valset);
        return res;
    }
    if (valset->res != NO_ERR) {
        res = valset->res;
        val_free_value(valset);
        return res;
    }

    /* get the expr parameter */
    expr = val_find_child(valset, 
                          YANGCLI_MOD, 
                          YANGCLI_EXPR);
    if (expr == NULL) {
        res = ERR_NCX_MISSING_PARM;
    } else if (expr->res != NO_ERR) {
        res = expr->res;
    }

    if (res == NO_ERR) {
        /* get the optional docroot parameter */
        docroot = val_find_child(valset, 
                                 YANGCLI_MOD, 
                                 YANGCLI_DOCROOT);
        if (docroot != NULL) {
            if (docroot->res != NO_ERR) {
                res = docroot->res;
            } else {
                val_remove_child(docroot);
            }
        }
    }

    if (res == NO_ERR && docroot == NULL) {
        dummydoc = xml_val_new_struct(NCX_EL_DATA, xmlns_nc_id());
        if (dummydoc == NULL) {
            res = ERR_INTERNAL_MEM;
        } else {
            docroot = dummydoc;
        }
    }

    if (res == NO_ERR) {
        /* get the optional maxloops parameter */
        maxloops = val_find_child(valset, 
                                  YANGCLI_MOD, 
                                  YANGCLI_MAXLOOPS);
        if (maxloops != NULL) {
            if (maxloops->res != NO_ERR) {
                res = maxloops->res;
            } else {
                maxloopsval = VAL_UINT(maxloops);
            }
        }
    }

    if (res == NO_ERR) {
        /* got all the parameters, and setup the XPath control block */
        pcb = xpath_new_pcb_ex(VAL_STR(expr), 
                               xpath_getvar_fn,
                               server_cb->runstack_context);
        if (pcb == NULL) {
            res = ERR_INTERNAL_MEM;
        } else {
            /* save these parameter and start a new while context block */
            res = runstack_handle_while(server_cb->runstack_context,
                                        maxloopsval,
                                        pcb,  /* hand off memory here */
                                        docroot);  /* hand off memory here */
            if (res == NO_ERR) {
                /* hand off the pcb and docroot memory above */
                pcb = NULL;
                docroot = NULL;
            }
        }
    }

    /* cleanup and exit */
    if (valset) {
        val_free_value(valset);
    }
    if (pcb) {
        xpath_free_pcb(pcb);
    }
    if (docroot) {
        val_free_value(docroot);
    }
    return res;

}  /* do_while */
/********************************************************************
 * FUNCTION do_elif (local RPC)
 * 
 * Handle the if command; start a new ifcb context
 *
 * elif expr='xpath-str' [docroot=$foo]
 *
 * INPUTS:
 *    server_cb == server control block to use
 *    rpc == RPC method for the show command
 *    line == CLI input in progress
 *    len == offset into line buffer to start parsing
 *    isif == TRUE for if, FALSE for elif
 * RETURNS:
 *   status
 *********************************************************************/
static status_t
    do_if_elif (server_cb_t *server_cb,
                obj_template_t *rpc,
                const xmlChar *line,
                uint32  len,
                boolean isif)
{
    val_value_t        *valset, *docroot, *expr, *dummydoc;
    xpath_pcb_t        *pcb;
    xpath_result_t     *result;
    status_t            res;
    boolean             cond;

    docroot = NULL;
    expr = NULL;
    pcb = NULL;
    dummydoc = NULL;
    cond = FALSE;
    res = NO_ERR;

    valset = get_valset(server_cb, rpc, &line[len], &res);
    if (valset == NULL) {
        return res;
    }
    if (res != NO_ERR) {
        val_free_value(valset);
        return res;
    }
    if (valset->res != NO_ERR) {
        res = valset->res;
        val_free_value(valset);
        return res;
    }

    /* get the expr parameter */
    expr = val_find_child(valset, 
                          YANGCLI_MOD, 
                          YANGCLI_EXPR);
    if (expr == NULL) {
        res = ERR_NCX_MISSING_PARM;
    } else if (expr->res != NO_ERR) {
        res = expr->res;
    }

    if (res == NO_ERR) {
        /* get the optional docroot parameter */
        docroot = val_find_child(valset, 
                                 YANGCLI_MOD, 
                                 YANGCLI_DOCROOT);
        if (docroot && docroot->res != NO_ERR) {
            res = docroot->res;
        }
    }

    if (res == NO_ERR && docroot == NULL) {
        dummydoc = xml_val_new_struct(NCX_EL_DATA, xmlns_nc_id());
        if (dummydoc == NULL) {
            res = ERR_INTERNAL_MEM;
        } else {
            docroot = dummydoc;
        }
    }

    if (res == NO_ERR) {
        /* got all the parameters, and setup the XPath control block */
        pcb = xpath_new_pcb_ex(VAL_STR(expr), 
                               xpath_getvar_fn,
                               server_cb->runstack_context);
        if (pcb == NULL) {
            res = ERR_INTERNAL_MEM;
        } else if ((isif && 
                    runstack_get_cond_state(server_cb->runstack_context)) ||
                   (!isif && 
                    !runstack_get_if_used(server_cb->runstack_context))) {

            /* figure out if this if or elif block is enabled or not */
            result = xpath1_eval_expr(pcb, 
                                      docroot, /* context */
                                      docroot,
                                      TRUE,
                                      FALSE,
                                      &res);
            if (result != NULL && res == NO_ERR) {
                /* get new condition state for this loop */
                cond = xpath_cvt_boolean(result);
            } 
            xpath_free_result(result);
        }

        if (res == NO_ERR) {
            if (isif) {
                res = runstack_handle_if(server_cb->runstack_context, cond);
            } else {
                res = runstack_handle_elif(server_cb->runstack_context, cond);
            }
        }
    }

    /* cleanup and exit */
    if (valset) {
        val_free_value(valset);
    }
    if (pcb) {
        xpath_free_pcb(pcb);
    }
    if (dummydoc) {
        val_free_value(dummydoc);
    }
    return res;

}  /* do_if_elif */