/******************************************************************** * FUNCTION agt_ses_new_dummy_session * * Create a dummy session control block * * INPUTS: * none * RETURNS: * pointer to initialized dummy SCB, or NULL if malloc error *********************************************************************/ ses_cb_t * agt_ses_new_dummy_session (void) { ses_cb_t *scb; if (!agt_ses_init_done) { agt_ses_init(); } /* check if dummy session already cached */ if (agtses[0]) { SET_ERROR(ERR_INTERNAL_INIT_SEQ); return NULL; } /* no, so create it */ scb = ses_new_dummy_scb(); if (!scb) { return NULL; } agtses[0] = scb; return scb; } /* agt_ses_new_dummy_session */
/******************************************************************** * FUNCTION agt_ses_set_dummy_session_acm * * Set the session ID and username of the user that * will be responsible for the rollback if needed * * INPUTS: * dummy_session == session control block to change * use_sid == Session ID to use for the rollback * * RETURNS: * status *********************************************************************/ status_t agt_ses_set_dummy_session_acm (ses_cb_t *dummy_session, ses_id_t use_sid) { ses_cb_t *scb; assert( dummy_session && "dummy_session is NULL!" ); if (!agt_ses_init_done) { agt_ses_init(); } scb = agtses[use_sid]; if (scb == NULL) { return ERR_NCX_INVALID_VALUE; } dummy_session->rollback_sid = use_sid; /*TODO Quick fix for confirmed-commit/rollback bug. */ /* Needs further investigation. */ dummy_session->sid = use_sid; if (scb == dummy_session) { return NO_ERR; /* skip -- nothing to do */ } if (dummy_session->username && scb->username) { m__free(dummy_session->username); dummy_session->username = NULL; } if (scb->username) { dummy_session->username = xml_strdup(scb->username); if (dummy_session->username == NULL) { return ERR_INTERNAL_MEM; } } if (dummy_session->peeraddr && scb->peeraddr) { m__free(dummy_session->peeraddr); dummy_session->peeraddr = NULL; } if (scb->peeraddr) { dummy_session->peeraddr = xml_strdup(scb->peeraddr); if (dummy_session->peeraddr == NULL) { return ERR_INTERNAL_MEM; } } return NO_ERR; } /* agt_ses_set_dummy_session_acm */
/******************************************************************** * FUNCTION agt_init2 * * Initialize the Server Library * The agt_profile is set and the object database is * ready to have YANG modules loaded * * RPC and data node callbacks should be installed * after the module is loaded, and before the running config * is loaded. * * RETURNS: * status *********************************************************************/ status_t agt_init2 (void) { val_value_t *clivalset; ncx_module_t *retmod; val_value_t *val; agt_dynlib_cb_t *dynlib; xmlChar *savestr, *revision, savechar; cfg_template_t *cfg; status_t res; uint32 modlen; boolean startup_loaded; log_debug3("\nServer Init-2 Starting..."); startup_loaded = FALSE; /* init user callback support */ agt_cb_init(); agt_commit_complete_init(); agt_commit_validate_init(); agt_not_queue_notification_cb_init(); /* initial signal handler first to allow clean exit */ agt_signal_init(); /* initialize the server timer service */ agt_timer_init(); /* initialize the RPC server callback structures */ res = agt_rpc_init(); if (res != NO_ERR) { log_debug3("\nError in rpc_init"); return res; } /* initialize the NCX connect handler */ res = agt_connect_init(); if (res != NO_ERR) { log_debug3("\nError in agt_connect_init"); return res; } /* initialize the NCX hello handler */ res = agt_hello_init(); if (res != NO_ERR) { log_debug3("\nError in agt_hello_init"); return res; } /* setup an empty <running> config * The config state is still CFG_ST_INIT * so no user access can occur yet (except OP_LOAD by root) */ res = cfg_init_static_db(NCX_CFGID_RUNNING); if (res != NO_ERR) { return res; } /* set the 'ordered-by system' sorted/not-sorted flag */ ncx_set_system_sorted(agt_profile.agt_system_sorted); /* set the 'top-level mandatory objects allowed' flag */ ncx_set_top_mandatory_allowed(!agt_profile.agt_running_error); /*** All Server profile parameters should be set by now ***/ /* must set the server capabilities after the profile is set */ res = agt_cap_set_caps(agt_profile.agt_targ, agt_profile.agt_start, agt_profile.agt_defaultStyle); if (res != NO_ERR) { return res; } /* setup the candidate config if it is used */ if (agt_profile.agt_targ==NCX_AGT_TARG_CANDIDATE) { res = cfg_init_static_db(NCX_CFGID_CANDIDATE); if (res != NO_ERR) { return res; } } /* setup the startup config if it is used */ if (agt_profile.agt_start==NCX_AGT_START_DISTINCT) { res = cfg_init_static_db(NCX_CFGID_STARTUP); if (res != NO_ERR) { return res; } } /* initialize the server access control model */ res = agt_acm_init(); if (res != NO_ERR) { return res; } /* initialize the session handler data structures */ agt_ses_init(); /* load the system module */ res = agt_sys_init(); if (res != NO_ERR) { return res; } /* load the NETCONF state monitoring data model module */ res = agt_state_init(); if (res != NO_ERR) { return res; } /* load the NETCONF Notifications data model module */ res = agt_not_init(); if (res != NO_ERR) { return res; } /* load the NETCONF /proc monitoring data model module */ res = agt_proc_init(); if (res != NO_ERR) { return res; } /* load the partial lock module */ res = y_ietf_netconf_partial_lock_init (y_ietf_netconf_partial_lock_M_ietf_netconf_partial_lock, NULL); if (res != NO_ERR) { return res; } #if 0 // OpenClovis: we do not want this by default /* load the NETCONF interface monitoring data model module */ res = agt_if_init(); if (res != NO_ERR) { return res; } #endif /* initialize the NCX server core callback functions. * the schema (yuma-netconf.yang) for these callbacks was * already loaded in the common ncx_init * */ res = agt_ncx_init(); if (res != NO_ERR) { return res; } /* load the yuma-time-filter module */ res = y_yuma_time_filter_init (y_yuma_time_filter_M_yuma_time_filter, NULL); if (res != NO_ERR) { return res; } /* load the yuma-arp module */ res = y_yuma_arp_init(y_yuma_arp_M_yuma_arp, NULL); if (res != NO_ERR) { return res; } /* check the module parameter set from CLI or conf file * for any modules to pre-load */ res = NO_ERR; clivalset = agt_cli_get_valset(); if (clivalset) { if (LOGDEBUG) { log_debug("\n\nnetconfd final CLI + .conf parameters:\n"); val_dump_value_max(clivalset, 0, NCX_DEF_INDENT, DUMP_VAL_LOG, NCX_DISPLAY_MODE_PLAIN, FALSE, /* withmeta */ TRUE /* config only */); log_debug("\n"); } /* first check if there are any deviations to load */ val = val_find_child(clivalset, NCXMOD_NETCONFD, NCX_EL_DEVIATION); while (val) { res = ncxmod_load_deviation(VAL_STR(val), &agt_profile.agt_savedevQ); if (res != NO_ERR) { return res; } else { val = val_find_next_child(clivalset, NCXMOD_NETCONFD, NCX_EL_DEVIATION, val); } } val = val_find_child(clivalset, NCXMOD_NETCONFD, NCX_EL_MODULE); /* attempt all dynamically loaded modules */ while (val && res == NO_ERR) { /* see if the revision is present in the * module parameter or not */ modlen = 0; revision = NULL; savestr = NULL; savechar = '\0'; if (yang_split_filename(VAL_STR(val), &modlen)) { savestr = &(VAL_STR(val)[modlen]); savechar = *savestr; *savestr = '\0'; revision = savestr + 1; } #ifdef STATIC_SERVER /* load just the module * SIL initialization is assumed to be * handled elsewhere */ res = ncxmod_load_module(VAL_STR(val), revision, &agt_profile.agt_savedevQ, &retmod); } #else /* load the SIL and it will load its own module */ res = agt_load_sil_code(VAL_STR(val), revision, FALSE); if (res == ERR_NCX_SKIPPED) { log_warn("\nWarning: SIL code for module '%s' not found", VAL_STR(val)); res = ncxmod_load_module(VAL_STR(val), revision, &agt_profile.agt_savedevQ, &retmod); } #endif if (savestr != NULL) { *savestr = savechar; } if (res == NO_ERR) { val = val_find_next_child(clivalset, NCXMOD_NETCONFD, NCX_EL_MODULE, val); } } }
/******************************************************************** * FUNCTION agt_ses_new_session * * Create a real agent session control block * * INPUTS: * transport == the transport type * fd == file descriptor number to use for IO * RETURNS: * pointer to initialized SCB, or NULL if some error * This pointer is stored in the session table, so it does * not have to be saved by the caller *********************************************************************/ ses_cb_t * agt_ses_new_session (ses_transport_t transport, int fd) { ses_cb_t *scb; agt_profile_t *profile; uint32 i, slot; status_t res; if (!agt_ses_init_done) { agt_ses_init(); } res = NO_ERR; slot = 0; scb = NULL; /* check if any sessions are available */ if (next_sesid == 0) { /* end has already been reached, so now in brute force * session reclaim mode */ slot = 0; for (i=1; i<AGT_SES_MAX_SESSIONS && !slot; i++) { if (!agtses[i]) { slot = i; } } } else { slot = next_sesid; } if (slot) { /* make sure there is memory for a session control block */ scb = ses_new_scb(); if (scb) { /* initialize the profile vars */ profile = agt_get_profile(); scb->linesize = profile->agt_linesize; scb->withdef = profile->agt_defaultStyleEnum; scb->indent = profile->agt_indent; if (ncx_protocol_enabled(NCX_PROTO_NETCONF10)) { scb->protocols_requested |= NCX_FL_PROTO_NETCONF10; } if (ncx_protocol_enabled(NCX_PROTO_NETCONF11)) { scb->protocols_requested |= NCX_FL_PROTO_NETCONF11; } /* initialize the static vars */ scb->type = SES_TYP_NETCONF; scb->transport = transport; scb->state = SES_ST_INIT; scb->mode = SES_MODE_XML; scb->sid = slot; scb->inready.sid = slot; scb->outready.sid = slot; scb->state = SES_ST_INIT; scb->fd = fd; scb->instate = SES_INST_IDLE; scb->stream_output = TRUE; res = ses_msg_new_buff(scb, TRUE, &scb->outbuff); } else { res = ERR_INTERNAL_MEM; } } else { res = ERR_NCX_RESOURCE_DENIED; } /* add the FD to SCB mapping in the definition registry */ if (res == NO_ERR) { res = def_reg_add_scb(scb->fd, scb); } /* check result and add to session array if NO_ERR */ if (res == NO_ERR) { agtses[slot] = scb; /* update the next slot now */ if (next_sesid) { if (++next_sesid==AGT_SES_MAX_SESSIONS) { /* reached the end */ next_sesid = 0; } } if (LOGINFO) { log_info("\nNew session %d created OK", slot); } agttotals->inSessions++; agttotals->active_sessions++; } else { if (scb) { agt_ses_free_session(scb); scb = NULL; } if (LOGINFO) { log_info("\nNew session request failed (%s)", get_error_string(res)); } } return scb; } /* agt_ses_new_session */