[PATCH V6 2/7] vlan extention - CIM model helper

From: Wenchao Xia <xiawenc@linux.vnet.ibm.com> This patch add helper functions for building up CIM network model. Signed-off-by: Wenchao Xia <xiawenc@linux.vnet.ibm.com> --- libxkutil/network_model_helper.c | 473 ++++++++++++++++++++++++++++++++++++++ libxkutil/network_model_helper.h | 101 ++++++++ 2 files changed, 574 insertions(+), 0 deletions(-) create mode 100644 libxkutil/network_model_helper.c create mode 100644 libxkutil/network_model_helper.h diff --git a/libxkutil/network_model_helper.c b/libxkutil/network_model_helper.c new file mode 100644 index 0000000..9bb3e83 --- /dev/null +++ b/libxkutil/network_model_helper.c @@ -0,0 +1,473 @@ +/* + * Copyright IBM Corp. 2012 + * + * Authors: + * Wenchao Xia <xiawenc@cn.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include <string.h> + +#include "network_model_helper.h" +#include "device_parsing.h" + +#include "cmpidt.h" +#include "cmpift.h" +#include "cmpimacs.h" + +/* this function would return a new allocated string or NULL */ +char *compare_and_switch_prefix(const char *orig_str, + const char *orig_prefix, + const char *dest_prefix) +{ + int orig_prefix_len, dest_prefix_len, asret; + char *retstr = NULL; + const char *suffix; + if (orig_str == NULL) { + goto out; + } + orig_prefix_len = strlen(orig_prefix); + dest_prefix_len = strlen(dest_prefix); + if (0 != strncmp(orig_str, orig_prefix, orig_prefix_len)) { + goto out; + } + suffix = orig_str + orig_prefix_len; + asret = asprintf(&retstr, "%s%s", dest_prefix, suffix); + if (asret == -1) { + free(retstr); + retstr = NULL; + } + out: + return retstr; +} + +char *switch_device_id_prefix(const char *whole_id, + const char *orig_prefix, + const char *dest_prefix) +{ + char *system = NULL; + char *device = NULL; + char *new_id = NULL; + char *retstr = NULL; + int asret; + + + if (0 == parse_fq_devid(whole_id, &system, &device)) { + goto out; + } + + new_id = compare_and_switch_prefix(device, + orig_prefix, dest_prefix); + + if (new_id == NULL) { + goto out; + } + asret = asprintf(&retstr, "%s/%s", system, new_id); + if (asret == -1) { + free(retstr); + retstr = NULL; + } + + out: + free(system); + free(device); + free(new_id); + return retstr; +} + +char *ep_id_to_easdea_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_PREFIX, ETHPORT_ALLOCATION_SD_PREFIX); +} + +char *easdea_id_to_ep_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_ALLOCATION_SD_PREFIX, ETHPORT_PREFIX); +} + +char *ep_id_to_easdec_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_PREFIX, ETHPORT_CONNECTION_SD_PREFIX); +} + +char *easdec_id_to_ep_id(const char *epid) +{ + return switch_device_id_prefix(epid, + ETHPORT_CONNECTION_SD_PREFIX, ETHPORT_PREFIX); +} + +char *vlanid_to_connection_name(const int id) +{ + int asret; + char *str = NULL; + char *prefix = CONNECTION_VLAN_PREFIX; + asret = asprintf(&str, "%s%d", prefix, id); + if (asret == -1) { + return NULL; + } + return str; +} + +int vlanid_from_connection_name(const char *name) +{ + int id = -1; + int temp = -1; + char *prefix = CONNECTION_VLAN_PREFIX; + char *dig_start, *dig_end; + if (name == NULL) { + goto out; + } + dig_start = strstr(name, prefix); + if (dig_start == NULL) { + goto out; + } + dig_start += strlen(prefix); + temp = strtol(dig_start, &dig_end, 10); + if ((dig_start == dig_end) || (temp < 0) || (temp > 4095)) { + goto out; + } + id = temp; + out: + return id; +} + +int eth_iface_filter_cim_ethport(const struct EthIface *piface, + void *nouse) +{ + if ((piface->eth_type != ETH_TYPE_NOT_GOT) && + (piface->eth_type != ETH_TYPE_ETHER_BRIDGE)) { + return 1; + } + return 0; +} + +int eth_iface_filter_cim_ethport_for_name(const struct EthIface *piface, + void *name) +{ + int cim_ethport_flag; + cim_ethport_flag = eth_iface_filter_cim_ethport(piface, NULL); + if (cim_ethport_flag == 1) { + if (0 == strcmp(piface->name, name)) { + return 1; + } + } + return 0; +} + +/* returned value need to be freed */ +char *get_ethportsd_name_from_iface(const char *iface_name, const int type) +{ + char *prefix; + char *name; + int size; + + if (iface_name == NULL) { + return NULL; + } + + if (type == EASD_TYPE_EA) { + prefix = ETHPORT_ALLOCATION_SD_PREFIX; + } else { + prefix = ETHPORT_CONNECTION_SD_PREFIX; + } + + size = strlen(iface_name)+strlen(prefix)+1; + CU_MALLOC(name, size); + snprintf(name, size, "%s%s", prefix, iface_name); + return name; +} + +/* returned value need to be freed */ +char *get_iface_name_from_ethportsd(const char *ethport_name, int *ptype) +{ + char *prefix; + char *name = NULL; + int size; + int prefix_len; + int t = -1; + + if (ethport_name == NULL) { + goto out; + } + + prefix = ETHPORT_ALLOCATION_SD_PREFIX; + prefix_len = strlen(prefix); + if (0 != strncmp(ethport_name, prefix, prefix_len)) { + prefix = ETHPORT_CONNECTION_SD_PREFIX; + prefix_len = strlen(prefix); + if (0 != strncmp(ethport_name, prefix, prefix_len)) { + goto out; + } else { + t = EASD_TYPE_EC; + } + } else { + t = EASD_TYPE_EA; + } + size = strlen(ethport_name)-strlen(prefix)+1; + CU_MALLOC(name, size); + snprintf(name, size, "%s", ethport_name+prefix_len); + + out: + if (ptype != NULL) { + *ptype = t; + } + return name; +} + +int eth_iface_filter_cim_switch(const struct EthIface *piface, + void *nouse) +{ + if (piface->eth_type == ETH_TYPE_ETHER_BRIDGE) { + return 1; + } + return eth_iface_filter_peths(piface, nouse); +} + +int eth_iface_filter_cim_switch_for_name(const struct EthIface *piface, + void *name) +{ + int cim_switch_flag; + cim_switch_flag = eth_iface_filter_cim_switch(piface, NULL); + if (cim_switch_flag == 1) { + if (0 == strcmp(piface->name, name)) { + return 1; + } + } + return 0; +} + +/* returned value need to be freed */ +char *get_switch_name_from_iface(const char *iface_name) +{ + char *prefix = SWITCH_PREFIX; + char *name; + int size; + + size = strlen(iface_name)+strlen(prefix)+1; + CU_MALLOC(name, size); + snprintf(name, size, "%s%s", prefix, iface_name); + return name; +} + +/* returned value need to be freed */ +char *get_iface_name_from_switch(const char *switch_name) +{ + char *prefix = SWITCH_PREFIX; + char *name; + int size; + int prefix_len; + + prefix_len = strlen(prefix); + if (0 != strncmp(switch_name, prefix, prefix_len)) { + return NULL; + } + size = strlen(switch_name)-strlen(prefix)+1; + CU_MALLOC(name, size); + snprintf(name, size, "%s", switch_name+prefix_len); + return name; +} + +/* returned value need to be freed */ +char *get_ethport_name_from_iface(const char *iface_name) +{ + char *prefix; + char *name; + int size; + + if (iface_name == NULL) { + return NULL; + } + + prefix = ETHPORT_PREFIX; + size = strlen(iface_name)+strlen(prefix)+1; + CU_MALLOC(name, size); + snprintf(name, size, "%s%s", prefix, iface_name); + return name; +} + +/* returned value need to be freed */ +char *get_iface_name_from_ethport(const char *ethport_name) +{ + char *prefix = ETHPORT_PREFIX; + char *name = NULL; + int size; + int prefix_len; + + if (ethport_name == NULL) { + goto out; + } + + prefix = ETHPORT_PREFIX; + prefix_len = strlen(prefix); + if (0 != strncmp(ethport_name, prefix, prefix_len)) { + goto out; + } + size = strlen(ethport_name)-prefix_len+1; + CU_MALLOC(name, size); + snprintf(name, size, "%s", ethport_name+prefix_len); + + out: + return name; +} + +/* determine the CIM switch from the piface */ +int get_possible_bridge_name_for_cim_model(struct EthIface *piface, + char **pbr1name, char **pbr2name) +{ + char *br1_name; + char *br2_name; + if (piface->attach_bridge != NULL) { + br1_name = get_switch_name_from_iface(piface->attach_bridge); + } else if (piface->dep_ifname != NULL) { + br1_name = get_switch_name_from_iface(piface->dep_ifname); + } else if (piface->eth_type == ETH_TYPE_ETHER_PHYSICAL) { + br1_name = get_switch_name_from_iface(piface->name); + } else { + br1_name = NULL; + } + + if ((piface->attach_bridge != NULL) && (piface->dep_ifname != NULL)) { + br2_name = get_switch_name_from_iface(piface->dep_ifname); + } else if ((piface->attach_bridge != NULL) && + (piface->eth_type == ETH_TYPE_ETHER_PHYSICAL)) { + br2_name = get_switch_name_from_iface(piface->name); + } else { + br2_name = NULL; + } + + /* incase some pifaces such as "lo" have no parent nor attaching + bridge */ + if (br1_name == NULL) { + br1_name = get_switch_name_from_iface(piface->name); + } + *pbr1name = br1_name; + *pbr2name = br2_name; + return 1; +} + +CMPIStatus get_array_uint16_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + int *ret_result, + int *ret_size, + int max_size) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIArray *array; + CMPICount array_size; + CMPIData elem; + int i, ret, count = 0; + + ret = cu_get_array_prop(inst, array_name, &array); + if (ret != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "array property not found."); + CU_DEBUG("Failed to get array property %s.", array_name); + goto out; + } + array_size = CMGetArrayCount(array, &s); + if ((s.rc != CMPI_RC_OK) || (array_size > max_size) || + (array_size <= 0)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to get size of array property," + " or its size is 0 or too big."); + CU_DEBUG("failed in getting size of %s property.", array_name); + goto out; + } + for (i = 0; i < array_size; i++) { + elem = CMGetArrayElementAt(array, i, NULL); + if (CMIsNullValue(elem)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "NULL content of array property."); + CU_DEBUG("NULL content of %s property.", array_name); + goto out; + } + if (!(elem.type & CMPI_INTEGER)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "wrong type of array property."); + CU_DEBUG("wrong type of %s property.", array_name); + goto out; + } + ret_result[count] = elem.value.uint16; + count++; + } + out: + *ret_size = count; + return s; +} + +CMPIStatus get_array_string_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + char **ret_result, + int *ret_size, + int max_size) +{ + CMPIStatus s = {CMPI_RC_OK, NULL}; + CMPIArray *array; + CMPICount array_size; + CMPIData elem; + const char *str; + int i, ret, count = 0; + + ret = cu_get_array_prop(inst, array_name, &array); + if (ret != CMPI_RC_OK) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "array property not found."); + CU_DEBUG("Failed to get array property %s.", array_name); + goto out; + } + array_size = CMGetArrayCount(array, &s); + if ((s.rc != CMPI_RC_OK) || (array_size > max_size) || + (array_size <= 0)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "failed to get size of array property," + " or its size is 0 or too big."); + CU_DEBUG("failed in getting size of %s property.", array_name); + goto out; + } + for (i = 0; i < array_size; i++) { + elem = CMGetArrayElementAt(array, i, NULL); + if (CMIsNullValue(elem)) { + cu_statusf(broker, &s, + CMPI_RC_ERR_FAILED, + "NULL content of array property."); + CU_DEBUG("NULL content of %s property.", array_name); + goto out; + } + str = NULL; + str = CMGetCharPtr(elem.value.string); + if (str == NULL) { + CU_DEBUG("Could not extract char pointer from " + "CMPIArray %s.", array_name); + goto out; + } + ret_result[count] = CU_STRDUP(str); + count++; + } + out: + *ret_size = count; + return s; +} diff --git a/libxkutil/network_model_helper.h b/libxkutil/network_model_helper.h new file mode 100644 index 0000000..6b3f151 --- /dev/null +++ b/libxkutil/network_model_helper.h @@ -0,0 +1,101 @@ +/* + * Copyright IBM Corp. 2012 + * + * Authors: + * Wenchao Xia <xiawenc@cn.ibm.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef NETWORK_MODEL_HELPER_H +#define NETWORK_MODEL_HELPER_H + +#include "network_parsing.h" + +#define EASD_TYPE_EA 1 +#define EASD_TYPE_EC 2 + +#define NETWORK_CLASS_PREFIX "Net" + +#define SWITCH_PREFIX "VS_" +#define VESSD_SYSTEM_PREFIX "Virt" +#define ETHPORT_PREFIX "EP_" +#define ETHPORT_ALLOCATION_SD_PREFIX "EA_" +#define ETHPORT_CONNECTION_SD_PREFIX "EC_" + +#define CONNECTION_VLAN_PREFIX "VLAN" + +#define CIM_NUM_NET_ETHERNET 2 +#define CIM_NUM_SWITCH_DEDICATED 38 +#define CIM_NUM_SWITCHPORT 30 +#define CIM_NUM_VLAN_MODE_TRUNK 5 +#define CIM_NUM_CONSUMERVISIBILITY_PASSEDTHROUGH 2 +#define CIM_NUM_CONSUMERVISIBILITY_VIRTUALIZED 3 + +char *get_switch_name_from_iface(const char *iface_name); +char *get_iface_name_from_switch(const char *switch_name); + +char *get_ethport_name_from_iface(const char *iface_name); +char *get_iface_name_from_ethport(const char *ethport_name); + +char *get_ethportsd_name_from_iface(const char *iface_name, const int type); +char *get_iface_name_from_ethportsd(const char *ethport_name, int *ptype); + +char *ep_id_to_easdea_id(const char *epid); +char *easdea_id_to_ep_id(const char *epid); +char *ep_id_to_easdec_id(const char *epid); +char *easdec_id_to_ep_id(const char *epid); + +char *vlanid_to_connection_name(const int id); +int vlanid_from_connection_name(const char *name); + +int eth_iface_filter_cim_switch(const struct EthIface *piface, + void *nouse); +int eth_iface_filter_cim_switch_for_name(const struct EthIface *piface, + void *name); +int eth_iface_filter_cim_ethport(const struct EthIface *piface, + void *nouse); +int eth_iface_filter_cim_ethport_for_name(const struct EthIface *piface, + void *name); + +int get_possible_bridge_name_for_cim_model(struct EthIface *piface, + char **pbr1name, char **pbr2name); + + +char *compare_and_switch_prefix(const char *orig_str, + const char *orig_prefix, + const char *dest_prefix); + +char *switch_device_id_prefix(const char *whole_id, + const char *orig_prefix, + const char *dest_prefix); + +/* other help function related to CIM */ +CMPIStatus get_array_uint16_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + int *ret_result, + int *ret_size, + int max_size); + +CMPIStatus get_array_string_from_instance(const CMPIBroker *broker, + CMPIInstance *inst, + char *array_name, + char **ret_result, + int *ret_size, + int max_size); + + +#endif -- 1.7.1
participants (1)
-
xiaxia347work@163.com