[Libvirt-cim] [PATCH 13/15] vlan extension - function lib - add the core structure

Wayne Xia xiawenc at linux.vnet.ibm.com
Wed Dec 7 09:25:46 UTC 2011


this is the core abstraction and structure for ethernet devices.

Signed-off-by: Wayne Xia <xiawenc at linux.vnet.ibm.com>
---
 libxkutil/host_network_basic.c |  639 ++++++++++++++++++++++++++++++++++++++++
 libxkutil/host_network_basic.h |  166 +++++++++++
 2 files changed, 805 insertions(+), 0 deletions(-)
 create mode 100644 libxkutil/host_network_basic.c
 create mode 100644 libxkutil/host_network_basic.h

diff --git a/libxkutil/host_network_basic.c b/libxkutil/host_network_basic.c
new file mode 100644
index 0000000..3bcb32e
--- /dev/null
+++ b/libxkutil/host_network_basic.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Wenchao Xia <xiawenc at 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.
+ */
+
+#include "host_network_basic.h"
+#include "host_network_helper.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+static void vlan_prop_print(VLAN_Prop *pvlan_prop)
+{
+    VLAN_Prop_8021q *p_8021q;
+    char *ingress = NULL, *egress = NULL;
+    CMD_DEBUG(1, "--VLAN props: type %d.\n",
+            pvlan_prop->vlan_type);
+    if (pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) {
+        p_8021q = &(pvlan_prop->props.prop_8021q);
+        vlan_8021q_qos_num_to_str(&ingress, &(p_8021q->ingress));
+        vlan_8021q_qos_num_to_str(&egress, &(p_8021q->egress));
+        CMD_DEBUG(1, "----IEEE802.1.Q: id %d, reorder %d, priority %d, "
+                "ingress %s, egress %s, parent %s.\n",
+                p_8021q->vlan_id, p_8021q->reorder_hdr, p_8021q->priv_flag,
+                ingress, egress, p_8021q->parent);
+    }
+    SAFE_FREE(ingress);
+    SAFE_FREE(egress);
+}
+
+static void br_prop_print(BR_Prop *pbr_prop)
+{
+    int i = 0;
+    CMD_DEBUG(1, "--Bridge props: id %s, stp %d, "
+            "bridge type %d, port_num %d.\n",
+            pbr_prop->bridge_id, pbr_prop->STP,
+            pbr_prop->type, pbr_prop->port_num);
+    if (pbr_prop->port_names != NULL) {
+        CMD_DEBUG(1, "----Ports attached: ");
+        while (i < pbr_prop->port_num) {
+            CMD_DEBUG(1, " %s,", *(pbr_prop->port_names+i));
+            i++;
+        }
+        CMD_DEBUG(1, "\n");
+    }
+}
+
+void eth_iface_print(EthIface *piface)
+{
+    CMD_DEBUG(1, "Iface device: name %s.\n"
+        "--Main Props: parent %s, attach to %s, mac %s, ip %s, ip_mask %s,"
+        " RX %lld, TX %lld, state %d, iface type %d.\n",
+        piface->name, piface->dep_ifname, piface->attach_bridge,
+        piface->mac, piface->ipv4_prop.ip, piface->ipv4_prop.ip_mask,
+        piface->run_prop.rx_bytes, piface->run_prop.tx_bytes,
+        piface->run_prop.state, piface->eth_type);
+    if (piface->pbr_prop != NULL) {
+        br_prop_print(piface->pbr_prop);
+    }
+    if (piface->pvlan_prop != NULL) {
+        vlan_prop_print(piface->pvlan_prop);
+    }
+    return;
+}
+
+void eth_ifaceslist_print(EthIfacesList *plist)
+{
+    int i = 0;
+    CMD_DEBUG(1, "Have %d ifaces in the list:\n", plist->count);
+    while (i < plist->count) {
+        CMD_DEBUG(1, "%04d ", i);
+        eth_iface_print(plist->pifaces[i]);
+        i++;
+    }
+}
+
+void vlan_prop_init(VLAN_Prop *pvlan_prop, int vlan_type)
+{
+    VLAN_Prop_8021q *p_8021q;
+    memset(pvlan_prop, 0, sizeof(VLAN_Prop));
+    pvlan_prop->vlan_type = vlan_type;
+    if (pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) {
+        p_8021q = &(pvlan_prop->props.prop_8021q);
+        p_8021q->ingress.count = NUM_NOT_GOT;
+        p_8021q->egress.count = NUM_NOT_GOT;
+        p_8021q->vlan_id = NUM_NOT_GOT;
+        p_8021q->reorder_hdr = NUM_NOT_GOT;
+        p_8021q->priv_flag = NUM_NOT_GOT;
+    }
+}
+
+void br_prop_init(BR_Prop *pbr_prop)
+{
+    memset(pbr_prop, 0, sizeof(BR_Prop));
+    pbr_prop->STP = NUM_NOT_GOT;
+    pbr_prop->type = BR_TYPE_NOT_GOT;
+    pbr_prop->port_num = NUM_NOT_GOT;
+}
+
+void eth_iface_init(EthIface *piface)
+{
+    memset(piface, 0, sizeof(EthIface));
+    piface->eth_type = ETH_TYPE_NOT_GOT;
+    piface->run_prop.rx_bytes = NUM_NOT_GOT;
+    piface->run_prop.tx_bytes = NUM_NOT_GOT;
+    piface->run_prop.state = ETH_STATE_NOT_GOT;
+    return;
+}
+
+void eth_iface_add_br_prop(EthIface *piface)
+{
+    SAFE_MALLOC(piface->pbr_prop, sizeof(BR_Prop));
+    br_prop_init(piface->pbr_prop);
+}
+
+void eth_iface_add_vlan_prop(EthIface *piface, int vlan_type)
+{
+    SAFE_MALLOC(piface->pvlan_prop, sizeof(VLAN_Prop));
+    vlan_prop_init(piface->pvlan_prop, vlan_type);
+}
+
+void vlan_prop_uninit(VLAN_Prop *pvlan_prop)
+{
+    VLAN_Prop_8021q *p_8021q;
+    if (pvlan_prop == NULL) {
+        return;
+    }
+    if (pvlan_prop->vlan_type == VLAN_TYPE_802_1_Q) {
+        p_8021q = &(pvlan_prop->props.prop_8021q);
+        SAFE_FREE(p_8021q->parent);
+    }
+}
+
+void br_prop_uninit(BR_Prop *pbr_prop)
+{
+    int i;
+    if (pbr_prop == NULL) {
+        return;
+    }
+    SAFE_FREE(pbr_prop->bridge_id);
+    i = 0;
+    if (pbr_prop->port_names != NULL) {
+        while (i < pbr_prop->port_num) {
+            SAFE_FREE(pbr_prop->port_names[i]);
+            i++;
+        }
+        SAFE_FREE(pbr_prop->port_names);
+    }
+}
+
+void eth_iface_uninit(EthIface *piface)
+{
+    if (piface == NULL) {
+        return;
+    }
+    SAFE_FREE(piface->name);
+    SAFE_FREE(piface->dep_ifname);
+    SAFE_FREE(piface->attach_bridge);
+    SAFE_FREE(piface->mac);
+    SAFE_FREE(piface->ipv4_prop.ip);
+    SAFE_FREE(piface->ipv4_prop.ip_mask);
+    br_prop_uninit(piface->pbr_prop);
+    SAFE_FREE(piface->pbr_prop);
+    vlan_prop_uninit(piface->pvlan_prop);
+    SAFE_FREE(piface->pvlan_prop);
+    return;
+}
+
+void eth_ifaces_clear(EthIface **ppifaces, int num)
+{
+    EthIface **t;
+    int i;
+    if (num <= 0) {
+        return;
+    }
+    t = ppifaces;
+    i = 0;
+    while (i < num) {
+        if (*t != NULL) {
+            eth_iface_uninit(*t);
+            SAFE_FREE(*t);
+        }
+        t++;
+        i++;
+    }
+    return;
+}
+
+void eth_ifaceslist_init(EthIfacesList *plist)
+{
+    plist->count = 0;
+}
+
+void eth_ifaceslist_uninit(EthIfacesList *plist)
+{
+    eth_ifaces_clear(plist->pifaces, plist->count);
+}
+
+static void vlan_prop_dup(VLAN_Prop *dest, const VLAN_Prop *src)
+{
+    VLAN_Prop_8021q *pd_8021q;
+    const VLAN_Prop_8021q *ps_8021q;
+    dest->vlan_type = src->vlan_type;
+    if (dest->vlan_type == VLAN_TYPE_802_1_Q) {
+        pd_8021q = &(dest->props.prop_8021q);
+        ps_8021q = &(src->props.prop_8021q);
+        pd_8021q->vlan_id = ps_8021q->vlan_id;
+        pd_8021q->reorder_hdr = ps_8021q->reorder_hdr;
+        pd_8021q->priv_flag = ps_8021q->priv_flag;
+        pd_8021q->ingress = ps_8021q->ingress;
+        pd_8021q->egress = ps_8021q->egress;
+        pd_8021q->parent = SAFE_STRDUP(ps_8021q->parent);
+    }
+}
+
+static void br_prop_dup(BR_Prop *dest, const BR_Prop *src)
+{
+    int i;
+    dest->bridge_id = SAFE_STRDUP(src->bridge_id);
+    dest->STP = src->STP;
+    dest->type = src->type;
+    SAFE_PSTR_ARRAY_DUP(dest->port_names, dest->port_num,
+                            src->port_names, src->port_num, i);
+}
+
+void eth_iface_dup(EthIface *dest, const EthIface *src)
+{
+    dest->name = SAFE_STRDUP(src->name);
+    dest->dep_ifname = SAFE_STRDUP(src->dep_ifname);
+    dest->attach_bridge = SAFE_STRDUP(src->attach_bridge);
+    dest->mac = SAFE_STRDUP(src->mac);
+    dest->eth_type = src->eth_type;
+    dest->ipv4_prop.ip = SAFE_STRDUP(src->ipv4_prop.ip);
+    dest->ipv4_prop.ip_mask = SAFE_STRDUP(src->ipv4_prop.ip_mask);
+    dest->run_prop.rx_bytes = src->run_prop.rx_bytes;
+    dest->run_prop.tx_bytes = src->run_prop.tx_bytes;
+    dest->run_prop.state = src->run_prop.state;
+
+    if (src->pbr_prop != NULL) {
+        SAFE_MALLOC(dest->pbr_prop, sizeof(BR_Prop));
+        /* doesn't need init it for that it would be copied at once */
+        br_prop_dup(dest->pbr_prop, src->pbr_prop);
+    } else {
+        dest->pbr_prop = NULL;
+    }
+
+    if (src->pvlan_prop != NULL) {
+        SAFE_MALLOC(dest->pvlan_prop, sizeof(VLAN_Prop));
+        /* doesn't need init it for that it would be copied at once */
+        vlan_prop_dup(dest->pvlan_prop, src->pvlan_prop);
+    } else {
+        dest->pvlan_prop = NULL;
+    }
+
+}
+
+int eth_iface_compare(const EthIface *p1, const EthIface *p2)
+{
+    int ret = 0;
+    if ((p1->name != NULL) || (p2->name != NULL)) {
+        if (0 == strcmp(p1->name, p2->name)) {
+            ret = 1;
+        }
+    }
+    return ret;
+}
+
+static void vlan_prop_merge(VLAN_Prop *pdest, VLAN_Prop *psrc, int style)
+{
+    VLAN_Prop_8021q *pd_8021q, *ps_8021q;
+
+    NUM_MERGE(pdest->vlan_type, psrc->vlan_type, VLAN_TYPE_NOT_GOT);
+
+    if (psrc->vlan_type == VLAN_TYPE_802_1_Q) {
+        pd_8021q = &(pdest->props.prop_8021q);
+        ps_8021q = &(psrc->props.prop_8021q);
+        NUM_MERGE(pd_8021q->vlan_id, ps_8021q->vlan_id, NUM_NOT_GOT);
+        NUM_MERGE(pd_8021q->reorder_hdr, ps_8021q->reorder_hdr, NUM_NOT_GOT);
+        NUM_MERGE(pd_8021q->priv_flag, ps_8021q->priv_flag, NUM_NOT_GOT);
+        if (pd_8021q->ingress.count == NUM_NOT_GOT) {
+            pd_8021q->ingress = ps_8021q->ingress;
+        }
+        if (pd_8021q->egress.count == NUM_NOT_GOT) {
+            pd_8021q->egress = ps_8021q->egress;
+        }
+        if (style == 0) {
+            CHARS_MERGE_NORMAL(pd_8021q->parent, ps_8021q->parent);
+        } else {
+            CHARS_MERGE_MOVE(pd_8021q->parent, ps_8021q->parent);
+        }
+    }
+}
+
+static void br_prop_merge(BR_Prop *pdest, BR_Prop *psrc, int style)
+{
+    int i;
+
+    if (style == 0) {
+        CHARS_MERGE_NORMAL(pdest->bridge_id, psrc->bridge_id);
+        /*merge it when dest have not been set */
+        if (pdest->port_names == NULL) {
+            SAFE_PSTR_ARRAY_DUP(pdest->port_names, pdest->port_num,
+                                psrc->port_names, psrc->port_num, i);
+        }
+    } else {
+        CHARS_MERGE_MOVE(pdest->bridge_id, psrc->bridge_id);
+        /*merge it when dest have not been set */
+        if (pdest->port_names == NULL) {
+            pdest->port_names = psrc->port_names;
+            pdest->port_num = psrc->port_num;
+            psrc->port_names = NULL;
+            psrc->port_num = NUM_NOT_GOT;
+        }
+    }
+    NUM_MERGE(pdest->STP, psrc->STP, NUM_NOT_GOT);
+    NUM_MERGE(pdest->type, psrc->type, BR_TYPE_NOT_GOT);
+}
+
+void eth_iface_merge(EthIface *dest, EthIface *src, int style)
+{
+    if (style == 0) {
+        CHARS_MERGE_NORMAL(dest->name, src->name);
+        CHARS_MERGE_NORMAL(dest->dep_ifname, src->dep_ifname);
+        CHARS_MERGE_NORMAL(dest->attach_bridge, src->attach_bridge);
+        CHARS_MERGE_NORMAL(dest->mac, src->mac);
+        CHARS_MERGE_NORMAL(dest->ipv4_prop.ip, src->ipv4_prop.ip);
+        CHARS_MERGE_NORMAL(dest->ipv4_prop.ip_mask, src->ipv4_prop.ip_mask);
+    } else {
+        CHARS_MERGE_MOVE(dest->name, src->name);
+        CHARS_MERGE_MOVE(dest->dep_ifname, src->dep_ifname);
+        CHARS_MERGE_MOVE(dest->attach_bridge, src->attach_bridge);
+        CHARS_MERGE_MOVE(dest->mac, src->mac);
+        CHARS_MERGE_MOVE(dest->ipv4_prop.ip, src->ipv4_prop.ip);
+        CHARS_MERGE_MOVE(dest->ipv4_prop.ip_mask, src->ipv4_prop.ip_mask);
+    }
+    NUM_MERGE(dest->eth_type, src->eth_type, ETH_TYPE_NOT_GOT);
+    NUM_MERGE(dest->run_prop.rx_bytes, src->run_prop.rx_bytes,
+                                            NUM_NOT_GOT);
+    NUM_MERGE(dest->run_prop.tx_bytes, src->run_prop.tx_bytes,
+                                            NUM_NOT_GOT);
+    NUM_MERGE(dest->run_prop.state, src->run_prop.state, ETH_STATE_NOT_GOT);
+
+    if (src->pbr_prop != NULL) {
+        if (dest->pbr_prop == NULL) {
+            SAFE_MALLOC(dest->pbr_prop, sizeof(BR_Prop));
+            br_prop_init(dest->pbr_prop);
+        }
+    br_prop_merge(dest->pbr_prop, src->pbr_prop, style);
+    }
+
+    if (src->pvlan_prop != NULL) {
+        if (dest->pvlan_prop == NULL) {
+            SAFE_MALLOC(dest->pvlan_prop, sizeof(VLAN_Prop));
+            vlan_prop_init(dest->pvlan_prop, src->pvlan_prop->vlan_type);
+        }
+    vlan_prop_merge(dest->pvlan_prop, src->pvlan_prop, style);
+    }
+
+}
+
+/* compare qos values */
+static int VLAN_Qos_8021q_compare_by_ref(const VLAN_Qos_8021q *pqos,
+                                            const VLAN_Qos_8021q *pref)
+{
+    int ret = 1;
+    int i, j;
+    if (pref->count == NUM_NOT_GOT) {
+        /* do not need to compare*/
+        goto out;
+    }
+    if ((pref->count < 0) || (pref->count > 8)) {
+        ret = 0;
+        goto out;
+    }
+    if ((pqos->count < 0) || (pqos->count > 8)) {
+        ret = 0;
+        goto out;
+    }
+
+    i = 0;
+    while (i < pref->count) {
+        j = 0;
+        while (j < pqos->count) {
+            if (pref->values[i].from == pqos->values[j].from) {
+                if (pref->values[i].to != pqos->values[j].to) {
+                    ret = 0;
+                    goto out;
+                }
+                break;
+            }
+            j++;
+        }
+        if (j == pqos->count) {
+            ret = 0;
+            goto out;
+        }
+        i++;
+    }
+
+ out:
+    return ret;
+}
+
+static int vlan_prop_filter_by_ref(const VLAN_Prop *pvlan_prop, void *pref)
+{
+    int compare_result = 1;
+    VLAN_Prop *ref = (VLAN_Prop *)pref;
+    char *p1, *p2;
+    const VLAN_Prop_8021q *pd_8021q;
+    VLAN_Prop_8021q *pref_8021q;
+
+    NUM_COMPARE_BY_REF(pvlan_prop->vlan_type, ref->vlan_type,
+                        compare_result, VLAN_TYPE_NOT_GOT);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    if (ref->vlan_type == VLAN_TYPE_802_1_Q) {
+        pd_8021q = &(pvlan_prop->props.prop_8021q);
+        pref_8021q = &(ref->props.prop_8021q);
+
+        NUM_COMPARE_BY_REF(pd_8021q->vlan_id, pref_8021q->vlan_id,
+                        compare_result, NUM_NOT_GOT);
+        if (compare_result == 0) {
+            goto out;
+        }
+
+        NUM_COMPARE_BY_REF(pd_8021q->reorder_hdr, pref_8021q->reorder_hdr,
+                        compare_result, NUM_NOT_GOT);
+        if (compare_result == 0) {
+            goto out;
+        }
+
+        NUM_COMPARE_BY_REF(pd_8021q->priv_flag, pref_8021q->priv_flag,
+                        compare_result, NUM_NOT_GOT);
+        if (compare_result == 0) {
+            goto out;
+        }
+
+        compare_result = VLAN_Qos_8021q_compare_by_ref(&(pd_8021q->ingress),
+                                                       &(pref_8021q->ingress));
+        if (compare_result == 0) {
+            goto out;
+        }
+
+        compare_result = VLAN_Qos_8021q_compare_by_ref(&(pd_8021q->egress),
+                                                       &(pref_8021q->egress));
+        if (compare_result == 0) {
+            goto out;
+        }
+
+        p1 = pd_8021q->parent;
+        p2 = pref_8021q->parent;
+        CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+        if (compare_result == 0) {
+            goto out;
+        }
+    }
+
+ out:
+    return compare_result;
+
+}
+
+static int br_prop_filter_by_ref(const BR_Prop *pbr_prop, void *pref)
+{
+    int compare_result = 1;
+    BR_Prop *ref = (BR_Prop *)pref;
+    char *p1, *p2;
+
+    p1 = pbr_prop->bridge_id;
+    p2 = ref->bridge_id;
+    CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    NUM_COMPARE_BY_REF(pbr_prop->STP, ref->STP,
+                        compare_result, NUM_NOT_GOT);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    NUM_COMPARE_BY_REF(pbr_prop->type, ref->type,
+                        compare_result, BR_TYPE_NOT_GOT);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    NUM_COMPARE_BY_REF(pbr_prop->port_num, ref->port_num,
+                        compare_result, NUM_NOT_GOT);
+    /* skip the comparation of ports it attached, user can define
+    a special filter for that */
+ out:
+    return compare_result;
+}
+
+int eth_iface_filter_by_ref(const EthIface *piface, void *pref)
+{
+    int compare_result = 1;
+    EthIface *ref = (EthIface *)pref;
+    char *p1, *p2;
+
+    p1 = piface->name;
+    p2 = ref->name;
+    CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    p1 = piface->dep_ifname;
+    p2 = ref->dep_ifname;
+    CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    p1 = piface->attach_bridge;
+    p2 = ref->attach_bridge;
+    CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    p1 = piface->mac;
+    p2 = ref->mac;
+    CHARS_COMPARE_CASE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    NUM_COMPARE_BY_REF(piface->eth_type, ref->eth_type,
+                        compare_result, ETH_TYPE_NOT_GOT);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    p1 = piface->ipv4_prop.ip;
+    p2 = ref->ipv4_prop.ip;
+    CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    p1 = piface->ipv4_prop.ip_mask;
+    p2 = ref->ipv4_prop.ip_mask;
+    CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    NUM_COMPARE_BY_REF(piface->run_prop.state, ref->run_prop.state,
+                        compare_result, ETH_STATE_NOT_GOT);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+    if (ref->pbr_prop != NULL) {
+        if (piface->pbr_prop != NULL) {
+            compare_result = br_prop_filter_by_ref(piface->pbr_prop,
+                                                ref->pbr_prop);
+        } else {
+            compare_result = 0;
+        }
+        if (compare_result == 0) {
+            goto out;
+        }
+    }
+
+    if (ref->pvlan_prop != NULL) {
+        if (piface->pvlan_prop != NULL) {
+            compare_result = vlan_prop_filter_by_ref(piface->pvlan_prop,
+                                                ref->pvlan_prop);
+
+        } else {
+            compare_result = 0;
+        }
+        if (compare_result == 0) {
+            goto out;
+        }
+    }
+
+ out:
+    return compare_result;
+}
+
+int eth_iface_filter_by_refname(const EthIface *piface, void *pref)
+{
+    int compare_result = 1;
+    EthIface *ref = (EthIface *)pref;
+    char *p1, *p2;
+
+    p1 = piface->name;
+    p2 = ref->name;
+    CHARS_COMPARE_BY_REF(p1, p2, compare_result);
+    if (compare_result == 0) {
+        goto out;
+    }
+
+ out:
+    return compare_result;
+}
+
+int eth_iface_filter_vlans(const EthIface *piface, void *nouse)
+{
+    if (piface->name == NULL) {
+        return 0;
+    }
+    if (NULL == strstr(piface->name, ".")) {
+        return 0;
+    } else {
+        return 1;
+    }
+}
+
+/* the judgement condition is weak, but I can't find a better way */
+int eth_iface_filter_peths(const EthIface *piface, void *nouse)
+{
+    if (piface->name == NULL) {
+        return 0;
+    }
+    if (NULL == strstr(piface->name, ".")) {
+        if (0 == strncmp(piface->name, "eth", 3)) {
+            return 1;
+        } else {
+            return 0;
+        }
+    } else {
+        return 0;
+    }
+}
diff --git a/libxkutil/host_network_basic.h b/libxkutil/host_network_basic.h
new file mode 100644
index 0000000..d1dd128
--- /dev/null
+++ b/libxkutil/host_network_basic.h
@@ -0,0 +1,166 @@
+/*
+ * Copyright IBM Corp. 2011
+ *
+ * Authors:
+ *  Wenchao Xia <xiawenc at 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.
+ */
+
+#ifndef NETWORK_BASIC_HOST_H
+#define NETWORK_BASIC_HOST_H
+
+/* value defines */
+#define MAX_IFACE_NUM 4096
+
+#define NUM_NOT_GOT -1
+
+typedef enum {
+    ETH_STATE_NOT_GOT = NUM_NOT_GOT,
+    ETH_STATE_UNKNOWN = 0,
+    ETH_STATE_DOWN = 1,
+    ETH_STATE_UP = 2
+} EthState;
+
+typedef enum {
+    ETH_TYPE_NOT_GOT = NUM_NOT_GOT,
+    ETH_TYPE_UNKNOWN = 0,
+    ETH_TYPE_LOOPBACK = 1,
+    ETH_TYPE_PHYSICAL = 2,
+    ETH_TYPE_NORMAL = 4,
+    ETH_TYPE_BRIDGE = 8,
+    ETH_TYPE_VLAN = 16
+} EthType;
+
+typedef enum {
+    BR_TYPE_NOT_GOT = NUM_NOT_GOT,
+    BR_TYPE_UNKNOWN = 0,
+    BR_TYPE_SWITCH = 1,
+    BR_TYPE_NAT = 2
+} BrType;
+
+typedef enum {
+    VLAN_TYPE_NOT_GOT = NUM_NOT_GOT,
+    VLAN_TYPE_802_1_Q = 1,
+    VLAN_TYPE_802_1_QBG = 2,
+    VLAN_TYPE_802_1_QBH = 4
+} VLANType;
+
+/* structure defines */
+typedef struct IPV4_Prop {
+    char *ip;
+    char *ip_mask;
+} IPV4_Prop;
+
+typedef struct BR_Prop {
+    char *bridge_id;
+    int STP;
+    BrType type;
+    char **port_names;
+    int port_num;
+} BR_Prop;
+
+typedef struct Run_Prop {
+    long long rx_bytes;
+    long long tx_bytes;
+    EthState state;
+} Run_Prop;
+
+typedef struct VLAN_Qos_8021q_elem {
+    int from;
+    int to;
+} VLAN_Qos_8021q_elem;
+
+typedef struct VLAN_Qos_8021q {
+    VLAN_Qos_8021q_elem values[8];
+    int count;
+} VLAN_Qos_8021q;
+
+typedef struct VLAN_Prop_8021q {
+    int vlan_id;
+    int reorder_hdr;
+    int priv_flag;
+    VLAN_Qos_8021q ingress;
+    VLAN_Qos_8021q egress;
+    char *parent;
+} VLAN_Prop_8021q;
+
+/* HP vlan standard, TBD */
+typedef struct VLAN_Prop_8021qbg {
+    int invalid;
+} VLAN_Prop_8021qbg;
+
+/* Cisco and VMware vlan standard, TBD */
+typedef struct VLAN_Prop_8021qbh {
+    int invalid;
+} VLAN_Prop_8021qbh;
+
+typedef struct VLAN_Prop {
+    int vlan_type;
+    union {
+        VLAN_Prop_8021q prop_8021q;
+        VLAN_Prop_8021qbg prop_8021qbg;
+        VLAN_Prop_8021qbh prop_8021qbh;
+    } props;
+} VLAN_Prop;
+
+/* EthIface is logical devices include eth ports and bridges */
+typedef struct EthIface {
+    char *name;
+    char *dep_ifname; /* parent dev name */
+    char *attach_bridge; /* bridge the iface is attached to */
+    char *mac;
+    EthType eth_type;
+    Run_Prop run_prop;
+    IPV4_Prop ipv4_prop;
+    /* optional properties */
+    BR_Prop *pbr_prop;
+    VLAN_Prop *pvlan_prop;
+} EthIface;
+
+typedef struct EthIfacesList {
+    EthIface *pifaces[MAX_IFACE_NUM];
+    int count;
+} EthIfacesList;
+
+typedef int (*eth_iface_filter_func)(const EthIface *piface, void *opaque);
+
+/* uninit functions are only called when there is resource malloc */
+void vlan_prop_init(VLAN_Prop *pvlan_prop, int vlan_type);
+void vlan_prop_uninit(VLAN_Prop *pvlan_prop);
+
+void br_prop_init(BR_Prop *pbr_prop);
+void br_prop_uninit(BR_Prop *pbr_prop);
+
+void eth_iface_print(EthIface *piface);
+void eth_iface_init(EthIface *piface);
+void eth_iface_add_br_prop(EthIface *piface);
+void eth_iface_add_vlan_prop(EthIface *piface,  int vlan_type);
+void eth_iface_uninit(EthIface *piface);
+void eth_ifaces_clear(EthIface **ppifaces, int num);
+
+void eth_ifaceslist_init(EthIfacesList *plist);
+void eth_ifaceslist_uninit(EthIfacesList *plist);
+void eth_ifaceslist_print(EthIfacesList *plist);
+
+/* this function assume dest have been uninited if it was used before*/
+void eth_iface_dup(EthIface *dest, const EthIface *src);
+
+/* see if it is refered to the same device */
+int eth_iface_compare(const EthIface *p1, const EthIface *p2);
+
+/* merge the properties that dest do not have value set, if style is set to 1,
+   the char* properties was moved instead of copy, safely reduce the memory
+   fragments, but src is modified. */
+void eth_iface_merge(EthIface *dest, EthIface *src, int style);
+
+int eth_iface_filter_by_ref(const EthIface *piface, void *pref);
+int eth_iface_filter_by_refname(const EthIface *piface, void *pref);
+int eth_iface_filter_vlans(const EthIface *piface, void *nouse);
+int eth_iface_filter_peths(const EthIface *piface, void *nouse);
+
+
+#endif
-- 
1.7.6





More information about the Libvirt-cim mailing list