/** * Initialize this network driver. * - The core application configuration must be completed prior calling * - The driver should not be already initialized (if its the case, a no-op will occur) * - The pConfig parameter must not be NULL * * @param pConfig [in] a pointer to eucanetd system-wide configuration * @param pGni [in] a pointer to the Global Network Information structure * @return 0 on success. Integer number on failure. */ static int network_driver_init(eucanetdConfig *pConfig, globalNetworkInfo *pGni) { int rc = 0; LOGDEBUG("Initializing '%s' network driver.\n", DRIVER_NAME()); // Make sure our given pointer is valid if (!pConfig) { LOGERROR("Failure to initialize '%s' networking mode. Invalid configuration parameter provided.\n", DRIVER_NAME()); return (1); } // Are we already initialized? if (IS_INITIALIZED()) { LOGERROR("Networking '%s' mode already initialized. Skipping!\n", DRIVER_NAME()); return (0); } if (!pMidoConfig) { pMidoConfig = EUCA_ZALLOC_C(1, sizeof (mido_config)); } pMidoConfig->config = pConfig; rc = initialize_mido(pMidoConfig, pConfig, pGni); if (rc) { LOGERROR("could not initialize mido: please ensure that all required config options for VPCMIDO mode are set\n"); free_mido_config(pMidoConfig); EUCA_FREE(pMidoConfig); return (1); } // We are now initialized gInitialized = TRUE; return (0); }
//! //! For MIDONET VPC mode, all is done in this driver API. //! //! @param[in] pGni a pointer to the Global Network Information structure //! @param[in] pLni a pointer to the Local Network Information structure //! //! @return EUCANETD_RUN_NO_API or EUCANETD_RUN_ERROR_API //! //! @see //! //! @pre //! - Both pGni and pLni must not be NULL //! - The driver must be initialized prior to calling this API. //! //! @post //! //! @note //! static u32 network_driver_system_scrub(globalNetworkInfo * pGni, lni_t * pLni) { int rc = 0; u32 ret = EUCANETD_RUN_NO_API; char versionFile[EUCA_MAX_PATH]; LOGINFO("Scrubbing for '%s' network driver.\n", DRIVER_NAME()); bzero(versionFile, EUCA_MAX_PATH); // Is the driver initialized? if (!IS_INITIALIZED()) { LOGERROR("Failed to scub the system for network artifacts. Driver '%s' not initialized.\n", DRIVER_NAME()); return (ret); } // Are the global and local network view structures NULL? if (!pGni || !pLni) { LOGERROR("Failed to implement security-group artifacts for '%s' network driver. Invalid parameters provided.\n", DRIVER_NAME()); return (ret); } // if (PEER_IS_NC(eucanetdPeer)) { if (pMidoConfig) { free_mido_config(pMidoConfig); bzero(pMidoConfig, sizeof(mido_config)); } rc = initialize_mido(pMidoConfig, config->eucahome, config->flushmode, config->disable_l2_isolation, config->midoeucanetdhost, config->midogwhosts, config->midopubnw, config->midopubgwip, "169.254.0.0", "17"); if (rc) { LOGERROR("could not initialize mido config\n"); ret = EUCANETD_RUN_ERROR_API; } else { if ((rc = do_midonet_update(pGni, pMidoConfig)) != 0) { LOGERROR("could not update midonet: check log for details\n"); ret = EUCANETD_RUN_ERROR_API; } else { LOGINFO("new Eucalyptus/Midonet networking state sync: updated successfully\n"); snprintf(versionFile, EUCA_MAX_PATH, EUCALYPTUS_RUN_DIR "/global_network_info.version", config->eucahome); if (!strlen(pGni->version) || (str2file(pGni->version, versionFile, O_CREAT | O_TRUNC | O_WRONLY, 0644, FALSE) != EUCA_OK) ) { LOGWARN("failed to populate GNI version file '%s': check permissions and disk capacity\n", versionFile); } } } // } // return (EUCANETD_RUN_NO_API); return (ret); }
/** * Cleans up the network driver. This will work even if the initial initialization * fail for any reasons. This will reset anything that could have been half-way or * fully configured. If forceFlush is set, then a network flush will be performed. * @param pConfig [in] a pointer to eucanetd system-wide configuration * @param pGni [in] a pointer to the Global Network Information structure * @param forceFlush [in] set to TRUE if a network flush needs to be performed * @return 0 on success. Integer number on failure. */ static int network_driver_cleanup(eucanetdConfig *pConfig, globalNetworkInfo *pGni, boolean forceFlush) { int ret = 0; LOGINFO("Cleaning up '%s' network driver.\n", DRIVER_NAME()); if (forceFlush) { if (network_driver_system_flush(pConfig, pGni)) { LOGERROR("Fail to flush network artifacts during network driver cleanup. See above log errors for details.\n"); ret = 1; } } midonet_api_cleanup(); free_mido_config(pMidoConfig); EUCA_FREE(pMidoConfig); gInitialized = FALSE; return (ret); }
//! //! For MIDONET VPC mode, all is done in this driver API. //! //! @param[in] pGni a pointer to the Global Network Information structure //! @param[in] pLni a pointer to the Local Network Information structure //! //! @return EUCANETD_RUN_NO_API or EUCANETD_RUN_ERROR_API //! //! @see //! //! @pre //! - Both pGni and pLni must not be NULL //! - The driver must be initialized prior to calling this API. //! //! @post //! //! @note //! static u32 network_driver_system_scrub(globalNetworkInfo * pGni, lni_t * pLni) { int rc = 0; u32 ret = EUCANETD_RUN_NO_API; LOGINFO("Scrubbing for '%s' network driver.\n", DRIVER_NAME()); // Is the driver initialized? if (!IS_INITIALIZED()) { LOGERROR("Failed to scub the system for network artifacts. Driver '%s' not initialized.\n", DRIVER_NAME()); return (EUCANETD_RUN_NO_API); } // Are the global and local network view structures NULL? if (!pGni || !pLni) { LOGERROR("Failed to implement security-group artifacts for '%s' network driver. Invalid parameters provided.\n", DRIVER_NAME()); return (EUCANETD_RUN_NO_API); } // if (PEER_IS_NC(eucanetdPeer)) { if (pMidoConfig) { free_mido_config(pMidoConfig); bzero(pMidoConfig, sizeof(mido_config)); } rc = initialize_mido(pMidoConfig, config->eucahome, config->midosetupcore, config->midoeucanetdhost, config->midogwhost, config->midogwip, config->midogwiface, config->midopubnw, config->midopubgwip, "169.254.0.0", "17"); if (rc) { LOGERROR("could not initialize mido config\n"); ret = EUCANETD_RUN_ERROR_API; } else { if ((rc = do_midonet_update(pGni, pMidoConfig)) != 0) { LOGERROR("could not update midonet: check log for details\n"); ret = EUCANETD_RUN_ERROR_API; } else { LOGINFO("new Eucalyptus/Midonet networking state sync: updated successfully\n"); } } // } return (EUCANETD_RUN_NO_API); }
//! //! For MIDONET VPC mode, all is done in this driver API. //! //! @param[in] pGni a pointer to the Global Network Information structure //! @param[in] pLni a pointer to the Local Network Information structure //! //! @return EUCANETD_RUN_NO_API or EUCANETD_RUN_ERROR_API //! //! @see //! //! @pre //! - Both pGni and pLni must not be NULL //! - The driver must be initialized prior to calling this API. //! //! @post //! //! @note //! static u32 network_driver_system_scrub(globalNetworkInfo *pGni, globalNetworkInfo *pGniApplied, lni_t *pLni) { int rc = 0; u32 ret = EUCANETD_RUN_NO_API; char versionFile[EUCA_MAX_PATH]; int check_tz_attempts = 30; struct timeval tv; eucanetd_timer(&tv); // Make sure midoname buffer is available midonet_api_cache_midos_init(); if (!gTunnelZoneOk) { LOGDEBUG("Checking MidoNet tunnel-zone.\n"); rc = 1; } while (!gTunnelZoneOk) { // Check tunnel-zone rc = check_mido_tunnelzone(); if (rc) { if ((--check_tz_attempts) > 0) { sleep(3); } else { LOGERROR("Cannot proceed without a valid tunnel-zone.\n"); return (EUCANETD_RUN_ERROR_API); } } else { gTunnelZoneOk = TRUE; } } bzero(versionFile, EUCA_MAX_PATH); // Need a valid global network view if (!pGni) { LOGERROR("Failed to scrub the system for '%s' network driver. Invalid parameters provided.\n", DRIVER_NAME()); return (ret); } if (!IS_INITIALIZED() || (pGni && pGniApplied && cmp_gni_vpcmido_config(pGni, pGniApplied))) { LOGINFO("(re)initializing %s driver.\n", DRIVER_NAME()); if (pMidoConfig) { eucanetdConfig *configbak = pMidoConfig->config; free_mido_config(pMidoConfig); pMidoConfig->config = configbak; } else { LOGERROR("failed to (re)initialize config options: VPCMIDO driver not initialized\n"); return (EUCANETD_RUN_ERROR_API); } //rc = initialize_mido(pMidoConfig, config->eucahome, config->flushmode, // config->disable_l2_isolation, config->midoeucanetdhost, config->midogwhosts, // config->midopubnw, config->midopubgwip, "169.254.0.0", "17"); rc = initialize_mido(pMidoConfig, pMidoConfig->config, "169.254.0.0", "17"); if (rc) { LOGERROR("failed to (re)initialize config options\n"); return (EUCANETD_RUN_ERROR_API); } pGniApplied = NULL; } LOGTRACE("euca VPCMIDO system state: %s\n", midonet_api_system_changed == 0 ? "CLEAN" : "DIRTY"); rc = do_midonet_update(pGni, pGniApplied, pMidoConfig); if (rc != 0) { LOGERROR("failed to update midonet: check log for details\n"); if (rc < 0) { // Accept errors in instances/interface implementation. ret = EUCANETD_VPCMIDO_IFERROR; } else { ret = EUCANETD_RUN_ERROR_API; } } else { LOGTRACE("Networking state sync: updated successfully in %.2f ms\n", eucanetd_timer_usec(&tv) / 1000.0); } return (ret); }
//! //! Responsible for flushing any networking artifacts implemented by this //! network driver. //! //! @param[in] pGni a pointer to the Global Network Information structure //! //! @return 0 on success or 1 if any failure occurred. //! //! @see //! //! @pre //! The driver must be initialized already //! //! @post //! On success, all networking mode artifacts will be flushed from the system. If any //! failure occurred, the system is left in a non-deterministic state and a subsequent //! call to this API may resolve the remaining issues. //! static int network_driver_system_flush(globalNetworkInfo *pGni) { int rc = 0; int ret = 0; // Is our driver initialized? if (!IS_INITIALIZED()) { LOGERROR("Failed to flush the networking artifacts for '%s' network driver. Driver not initialized.\n", DRIVER_NAME()); return (1); } if (pMidoConfig->config->flushmode) { switch(pMidoConfig->config->flushmode) { case FLUSH_MIDO_DYNAMIC: LOGINFO("Flushing objects in MidoNet (keep the core intact)\n"); rc = do_midonet_teardown(pMidoConfig); if (rc) { ret = 1; } break; case FLUSH_MIDO_ALL: LOGINFO("Flush all objects in MidoNet\n"); rc = do_midonet_teardown(pMidoConfig); if (rc) { ret = 1; } break; case FLUSH_MIDO_CHECKDUPS: LOGINFO("Check for duplicate objects in MidoNet\n"); rc = do_midonet_delete_dups(pMidoConfig, TRUE); if (rc) { ret = 1; } break; case FLUSH_MIDO_DUPS: LOGINFO("Flush duplicate objects in MidoNet\n"); rc = do_midonet_delete_dups(pMidoConfig, FALSE); if (rc) { ret = 1; } break; case FLUSH_MIDO_CHECKUNCONNECTED: LOGINFO("Check for unconnected objects in MidoNet\n"); rc = do_midonet_delete_vpc_object(pMidoConfig, "unconnected", TRUE); if (rc) { ret = 1; } break; case FLUSH_MIDO_UNCONNECTED: LOGINFO("Flush unconnected objects in MidoNet\n"); rc = do_midonet_delete_vpc_object(pMidoConfig, "unconnected", FALSE); if (rc) { ret = 1; } break; case FLUSH_MIDO_CHECKVPC: LOGINFO("Check %s health in MidoNet\n", pMidoConfig->config->flushmodearg); rc = do_midonet_delete_vpc_object(pMidoConfig, pMidoConfig->config->flushmodearg, TRUE); if (rc) { ret = 1; } break; case FLUSH_MIDO_VPC: rc = do_midonet_delete_vpc_object(pMidoConfig, pMidoConfig->config->flushmodearg, FALSE); if (rc) { ret = 1; } break; case FLUSH_MIDO_LISTVPC: rc = do_midonet_delete_vpc_object(pMidoConfig, "list", TRUE); if (rc) { ret = 1; } break; case FLUSH_MIDO_TEST: do_midonet_delete_vpc_object(pMidoConfig, "test", TRUE); break; case FLUSH_NONE: default: LOGERROR("check for eucanetd bug: should never reach this point.\n"); break; } free_mido_config(pMidoConfig); EUCA_FREE(pMidoConfig); pMidoConfig = NULL; gInitialized = FALSE; } return (ret); }
/** * This API checks the new GNI against the system view to decide what really * needs to be done. * For MIDONET VPC mode, all is done in this driver API. * @param pConfig [in] a pointer to eucanetd system-wide configuration * @param pGni [in] a pointer to the Global Network Information structure * @param pGniApplied [in] a pointer to the previously successfully implemented GNI * @return A bitmask indicating what needs to be done. The following bits are * the ones to look for: EUCANETD_RUN_NETWORK_API, EUCANETD_RUN_SECURITY_GROUP_API * and EUCANETD_RUN_ADDRESSING_API. */ static u32 network_driver_system_scrub(eucanetdConfig *pConfig, globalNetworkInfo *pGni, globalNetworkInfo *pGniApplied) { int rc = 0; u32 ret = EUCANETD_RUN_NO_API; struct timeval tv; eucanetd_timer(&tv); // Make sure midoname buffer is available midonet_api_cache_midos_init(); // Need a valid global network view if (!pConfig || !pGni) { LOGERROR("Failed to scrub the system for '%s' network driver. Invalid parameters provided.\n", DRIVER_NAME()); return (ret); } int config_changed = cmp_gni_config(pGni, pGniApplied); if (!IS_INITIALIZED() || (pGni && config_changed)) { LOGINFO("(re)initializing %s driver.\n", DRIVER_NAME()); if (pMidoConfig) { free_mido_config(pMidoConfig); gInitialized = FALSE; } else { LOGERROR("failed to (re)initialize config options: VPCMIDO driver not initialized\n"); return (EUCANETD_RUN_ERROR_API); } rc = network_driver_init(pConfig, pGni); if (rc) { LOGERROR("failed to (re)initialize config options\n"); return (EUCANETD_RUN_ERROR_API); } pGniApplied = NULL; } if (config_changed & GNI_CONFIG_DIFF_MIDONODES) { pMidoConfig->midotz_ok = FALSE; } LOGTRACE("euca VPCMIDO system state: %s\n", midonet_api_system_changed == 0 ? "CLEAN" : "DIRTY"); rc = do_midonet_update(pGni, pGniApplied, pMidoConfig); if (rc != 0) { LOGERROR("failed to update midonet: check log for details\n"); switch (rc) { case -2: // Accept errors in instances/interface implementation. ret = EUCANETD_VPCMIDO_IFERROR; break; case -1: // Accept errors in gateway(s) implementation. ret = EUCANETD_VPCMIDO_GWERROR; break; default: ret = EUCANETD_RUN_ERROR_API; } } else { LOGTRACE("Networking state sync: updated successfully in %.2f ms\n", eucanetd_timer_usec(&tv) / 1000.0); pMidoConfig->config->mido_arptable_config_changed = FALSE; } return (ret); }