[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