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

Chip Vincent cvincent at linux.vnet.ibm.com
Fri Dec 23 20:10:02 UTC 2011


On 12/07/2011 04:25 AM, Wayne Xia wrote:
> 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++;
> +    }
> +}
Are these debug functions always needed? Perhaps they should be wrapped in a 
#ifdef DEBUG to keep the
code and runtime minimal.
> +
> +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)
I have not yet looked up the definition of EthIface but assume it's a struct. 
I'd prefer to see 'struct EthIface' so that's clear. In general, we should avoid 
using #defines and #typedefs to obscure the actual type of something.
> +{
> +    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);
These macro names are not obvious. Consider clarifying.
> +        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
Why not name 'NUM_NOT_GOT' to something like 'NONE' or 'NOT_DEFINED'?
> +
> +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;
What about IPv6?

> +
> +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


-- 
Chip Vincent
Open Virtualization
IBM Linux Technology Center
cvincent at linux.vnet.ibm.com




More information about the Libvirt-cim mailing list