//! //! 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]; struct timeval tv; LOGINFO("Scrubbing for '%s' network driver.\n", DRIVER_NAME()); eucanetd_timer(&tv); bzero(versionFile, EUCA_MAX_PATH); // Is the driver initialized? if (!IS_INITIALIZED()) { LOGERROR("Failed to scrub the system for network artifacts. Driver '%s' not initialized.\n", DRIVER_NAME()); return (ret); } // 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); } LOGDEBUG("midonet_api cache state: %s\n", midonet_api_dirty_cache == 0 ? "CLEAN" : "DIRTY"); 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("Networking state sync: updated successfully in %.2f ms\n", eucanetd_timer_usec(&tv) / 1000.0); } 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, 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) { LOGINFO("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); // Is the driver initialized? if (!IS_INITIALIZED()) { LOGERROR("Failed to scrub the system for network artifacts. Driver '%s' not initialized.\n", DRIVER_NAME()); return (ret); } // 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); } LOGTRACE("euca VPCMIDO cache 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"); // Invalidate mido cache - force repopulate midonet_api_system_changed = 1; ret = EUCANETD_RUN_ERROR_API; } else { LOGTRACE("Networking state sync: updated successfully in %.2f ms\n", eucanetd_timer_usec(&tv) / 1000.0); } return (ret); }
//! //! Function description. //! //! @param[in] ipsh pointer to the IP set handler structure //! //! @return //! //! @see //! //! @pre //! //! @post //! //! @note //! int ips_handler_repopulate(ips_handler * ipsh) { int rc = 0, nm = 0; FILE *FH = NULL; char buf[1024] = ""; char *strptr = NULL; char setname[64] = ""; char ipname[64] = "", *ip = NULL; struct timeval tv = { 0 }; eucanetd_timer_usec(&tv); if (!ipsh || !ipsh->init) { return (1); } rc = ips_handler_free(ipsh); if (rc) { return (1); } rc = ips_system_save(ipsh); if (rc) { LOGERROR("could not save current IPS rules to file, exiting re-populate\n"); return (1); } FH = fopen(ipsh->ips_file, "r"); if (!FH) { LOGERROR("could not open file for read '%s': check permissions\n", ipsh->ips_file); return (1); } while (fgets(buf, 1024, FH)) { if ((strptr = strchr(buf, '\n'))) { *strptr = '\0'; } if (strlen(buf) < 1) { continue; } while (buf[strlen(buf) - 1] == ' ') { buf[strlen(buf) - 1] = '\0'; } if (strstr(buf, "create")) { setname[0] = '\0'; sscanf(buf, "create %s", setname); if (strlen(setname)) { ips_handler_add_set(ipsh, setname); } } else if (strstr(buf, "add")) { ipname[0] = '\0'; sscanf(buf, "add %s %[0-9./]", setname, ipname); if (strlen(setname) && strlen(ipname)) { rc = cidrsplit(ipname, &ip, &nm); if (ip && strlen(ip) && nm >= 0 && nm <= 32) { LOGDEBUG("reading in from ipset: adding ip/nm %s/%d to ipset %s\n", SP(ip), nm, SP(setname)); ips_set_add_net(ipsh, setname, ip, nm); EUCA_FREE(ip); } } } else { LOGWARN("unknown IPS rule on ingress, rule will be thrown out: (%s)\n", buf); } } fclose(FH); LOGINFO("ips populated in %.2f ms.\n", eucanetd_timer_usec(&tv) / 1000.0); return (0); }
/** * Retrieves the current iptables system state. * * @param ipth [in] pointer to the IP table handler structure * * @return 0 on success or 1 if any failure occurred */ int ipt_handler_repopulate(ipt_handler *ipth) { int rc = 0; FILE *FH = NULL; char buf[1024] = ""; char tmpbuf[1024] = ""; char *strptr = NULL; char newrule[1024] = ""; char tablename[64] = ""; char chainname[64] = ""; char policyname[64] = ""; char counters[64] = ""; char counterstr[256] = ""; struct timeval tv = { 0 }; // long long int countersa, countersb; eucanetd_timer_usec(&tv); if (!ipth || !ipth->init) { LOGERROR("Invalid argument: cannot reinitialize NULL ipt handler.\n"); return (1); } rc = ipt_handler_free(ipth); if (rc) { LOGERROR("could not reinitialize ipt handler.\n"); return (1); } rc = ipt_system_save(ipth); if (rc) { LOGERROR("could not save current IPT rules to file, exiting re-populate\n"); return (1); } FH = fopen(ipth->ipt_file, "r"); if (!FH) { LOGERROR("could not open file for read '%s': check permissions\n", ipth->ipt_file); return (1); } while (fgets(buf, 1024, FH)) { if ((strptr = strchr(buf, '\n'))) { *strptr = '\0'; } if (strlen(buf) < 1) { continue; } while (buf[strlen(buf) - 1] == ' ') { buf[strlen(buf) - 1] = '\0'; } if (buf[0] == '*') { tablename[0] = '\0'; sscanf(buf, "%[*]%s", tmpbuf, tablename); if (strlen(tablename)) { ipt_handler_add_table(ipth, tablename); } } else if (buf[0] == ':') { chainname[0] = '\0'; sscanf(buf, "%[:]%s %s %s", tmpbuf, chainname, policyname, counters); if (strlen(chainname)) { ipt_table_add_chain(ipth, tablename, chainname, policyname, counters); } } else if (strstr(buf, "COMMIT")) { } else if (buf[0] == '#') { } else if (buf[0] == '[' && strstr(buf, "-A")) { // sscanf(buf, "[%lld:%lld] %[-A] %s", &countersa, &countersb, tmpbuf, chainname); sscanf(buf, "%s %[-A] %s", counterstr, tmpbuf, chainname); snprintf(newrule, 1024, "%s", strstr(buf, "-A")); // ipt_chain_insert_rule(ipth, tablename, chainname, newrule, countersa, countersb, IPT_NO_ORDER); ipt_chain_insert_rule(ipth, tablename, chainname, newrule, counterstr, IPT_NO_ORDER); } else { LOGWARN("unknown IPT rule on ingress, will be thrown out: (%s)\n", buf); } } fclose(FH); unlink_handler_file(ipth->ipt_file); LOGDEBUG("ipt populated in %.2f ms.\n", eucanetd_timer_usec(&tv) / 1000.0); 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, 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); }
/** * 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); }