δΊ 2011-12-24 4:10, Chip Vincent ει:
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(a)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(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.
> + */
> +
> +#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.
there is a macro in network_helper.h: #define CMD_DEBUG_LEVEL 2
if the CMD_DEBUG_LEVEL < number in CMD_DEBUG(number, ""), the code
would not be compiled.
> +
> +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.
OK, this style is brought from qemu...
> +{
> + 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.
OK.
> + 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(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.
> + */
> +
> +#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'?
I thought NUM_NOT_GOT was more precise to show the situation that
the information was not there. For eg, ifconfig would not show eth port
active state, but ip addr would give that information.
> +
> +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?
ignored.... it seems now configuration of vlan did not need IP
information, planning adding that in the future.
> +
> +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
--
Best Regards
Wayne Xia
mail:xiawenc@linux.vnet.ibm.com
tel:86-010-82450803