From: Wenchao Xia <xiawenc(a)linux.vnet.ibm.com>
This patch add helper functions for building up CIM network model.
Signed-off-by: Wenchao Xia <xiawenc(a)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(a)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(a)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