this patch have the structure defines and related functions, make program
in upper level easy to use.
Signed-off-by: Wenchao Xia <xiawenc(a)cn.ibm.com>
---
libnetwork/host_network_basic.c | 656 +++++++++++++++++++++++++++++++++++++++
libnetwork/host_network_basic.h | 158 ++++++++++
2 files changed, 814 insertions(+), 0 deletions(-)
create mode 100644 libnetwork/host_network_basic.c
create mode 100644 libnetwork/host_network_basic.h
diff --git a/libnetwork/host_network_basic.c b/libnetwork/host_network_basic.c
new file mode 100644
index 0000000..9260b33
--- /dev/null
+++ b/libnetwork/host_network_basic.c
@@ -0,0 +1,656 @@
+/*
+ * Copyright IBM Corp. 2012
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ */
+
+#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,"
+ " RX %lld, TX %lld, status %d, iface type 0x%x.\n",
+ piface->name, piface->dep_ifname, piface->attach_bridge,
+ piface->mac,
+ piface->run_prop.rx_bytes, piface->run_prop.tx_bytes,
+ piface->run_prop.status, 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.status = NUM_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);
+ 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);
+}
+
+int eth_ifaceslist_add(EthIfacesList *plist, EthIface *piface)
+{
+ if (plist->count >= MAX_IFACE_NUM) {
+ CU_DEBUG("too much device found.");
+ return 0;
+ }
+ SAFE_MALLOC(plist->pifaces[plist->count], sizeof(EthIface));
+ eth_iface_dup(plist->pifaces[plist->count], piface);
+ plist->count++;
+ return 1;
+}
+
+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->run_prop.rx_bytes = src->run_prop.rx_bytes;
+ dest->run_prop.tx_bytes = src->run_prop.tx_bytes;
+ dest->run_prop.status = src->run_prop.status;
+
+ 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);
+ } 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);
+ }
+
+ /* special case for eth_type*/
+ if (dest->eth_type == ETH_TYPE_NOT_GOT) {
+ dest->eth_type = src->eth_type;
+ } else {
+ if ((src->eth_type & ETH_TYPE_ETHER_ANY) &&
+ (dest->eth_type & ETH_TYPE_ETHER_ANY)) {
+ dest->eth_type |= (src->eth_type & ETH_TYPE_SUB_MASK);
+ }
+ }
+
+ 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.status, src->run_prop.status, NUM_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;
+ }
+
+ /* special case for eth_type */
+ NUM_COMPARE_BY_REF((piface->eth_type & ETH_TYPE_BASE_MASK),
+ (ref->eth_type & ETH_TYPE_BASE_MASK),
+ compare_result, ETH_TYPE_NOT_GOT);
+ if (compare_result == 0) {
+ goto out;
+ }
+ NUM_COMPARE_BY_REF((piface->eth_type & ETH_TYPE_SUB_MASK),
+ (ref->eth_type & ETH_TYPE_SUB_MASK),
+ compare_result, ETH_TYPE_NOT_GOT);
+ if (compare_result == 0) {
+ goto out;
+ }
+
+ NUM_COMPARE_BY_REF(piface->run_prop.status, ref->run_prop.status,
+ compare_result, NUM_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->eth_type & ETH_TYPE_ETHER_ANY)) {
+ return 0;
+ }
+ if (piface->eth_type & ETH_TYPE_ETHER_SUB_BRIDGE) {
+ return 0;
+ }
+ if (piface->eth_type & ETH_TYPE_ETHER_SUB_VLAN) {
+ return 0;
+ }
+ if (piface->dep_ifname != NULL) {
+ return 0;
+ }
+ if (NULL != strstr(piface->name, ".")) {
+ return 0;
+ }
+ /* this filter NetUSB etc */
+ if (NULL == strstr(piface->name, "eth")) {
+ return 0;
+ }
+
+ return 1;
+}
diff --git a/libnetwork/host_network_basic.h b/libnetwork/host_network_basic.h
new file mode 100644
index 0000000..f782e51
--- /dev/null
+++ b/libnetwork/host_network_basic.h
@@ -0,0 +1,158 @@
+/*
+ * Copyright IBM Corp. 2012
+ *
+ * Authors:
+ * Wenchao Xia <xiawenc(a)cn.ibm.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ */
+
+#ifndef NETWORK_BASIC_HOST_H
+#define NETWORK_BASIC_HOST_H
+
+#include "dll_magic.h"
+
+/* value defines */
+#define MAX_IFACE_NUM 4096
+
+#define NUM_NOT_GOT -1
+
+#define ETH_TYPE_BASE_MASK 0xff00
+#define ETH_TYPE_SUB_MASK 0x00ff
+typedef enum {
+ ETH_TYPE_NOT_GOT = 0x0000,
+ ETH_TYPE_UNKNOWN = 0x0100,
+ ETH_TYPE_OTHER = 0x0200,
+ ETH_TYPE_ETHER_ANY = 0x0400,
+ ETH_TYPE_ETHER_SUB_PHYSICAL = 0x0001,
+ ETH_TYPE_ETHER_SUB_BRIDGE = 0x0002,
+ ETH_TYPE_ETHER_SUB_VLAN = 0x0004
+} 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;
+
+typedef struct BR_Prop {
+ char *bridge_id;
+ int STP;
+ BrType type;
+ char **port_names;
+ int port_num;
+} BR_Prop;
+
+/* status use RFC 2863 operational status */
+typedef struct Run_Prop {
+ long long rx_bytes;
+ long long tx_bytes;
+ int status;
+} 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;
+ /* 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 */
+DLL_PUBLIC void vlan_prop_init(VLAN_Prop *pvlan_prop, int vlan_type);
+DLL_PUBLIC void vlan_prop_uninit(VLAN_Prop *pvlan_prop);
+
+DLL_PUBLIC void br_prop_init(BR_Prop *pbr_prop);
+DLL_PUBLIC void br_prop_uninit(BR_Prop *pbr_prop);
+
+DLL_PUBLIC void eth_iface_print(EthIface *piface);
+DLL_PUBLIC void eth_iface_init(EthIface *piface);
+DLL_PUBLIC void eth_iface_add_br_prop(EthIface *piface);
+DLL_PUBLIC void eth_iface_add_vlan_prop(EthIface *piface, int vlan_type);
+DLL_PUBLIC void eth_iface_uninit(EthIface *piface);
+DLL_PUBLIC void eth_ifaces_clear(EthIface **ppifaces, int num);
+
+DLL_PUBLIC void eth_ifaceslist_init(EthIfacesList *plist);
+DLL_PUBLIC void eth_ifaceslist_uninit(EthIfacesList *plist);
+DLL_PUBLIC void eth_ifaceslist_print(EthIfacesList *plist);
+DLL_PUBLIC int eth_ifaceslist_add(EthIfacesList *plist, EthIface *piface);
+
+/* this function assume dest have been uninited if it was used before*/
+DLL_PUBLIC void eth_iface_dup(EthIface *dest, const EthIface *src);
+
+/* see if it is refered to the same device */
+DLL_PUBLIC 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. */
+DLL_PUBLIC void eth_iface_merge(EthIface *dest, EthIface *src, int style);
+
+DLL_PUBLIC int eth_iface_filter_by_ref(const EthIface *piface, void *pref);
+DLL_PUBLIC int eth_iface_filter_by_refname(const EthIface *piface, void *pref);
+DLL_PUBLIC int eth_iface_filter_vlans(const EthIface *piface, void *nouse);
+DLL_PUBLIC int eth_iface_filter_peths(const EthIface *piface, void *nouse);
+
+
+#endif
--
1.7.1