[Libvirt-cim] [PATCH 15/15] vlan extension - function lib - add the implemention of commandline

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


this file use tools ip, brctl, ifconfig to provide the functionalities.

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

diff --git a/libxkutil/host_network_implement_cmdline.c b/libxkutil/host_network_implement_cmdline.c
new file mode 100644
index 0000000..fc9226b
--- /dev/null
+++ b/libxkutil/host_network_implement_cmdline.c
@@ -0,0 +1,2002 @@
+/*
+ * 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.
+ *
+ * Note:
+ * the string example used below is all reformed to avoid code format check
+ * errors, so it just says the command output format as a reference.
+ * char "tab" is changed to "space", tailing space is removed, lines over 80
+ * characters was foldered.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#include "host_network_implement_cmdline.h"
+#include "host_network_helper.h"
+#include "host_network_error.h"
+
+/* macro defines */
+#define COMMAND_NOTFOUND_STRING "command not found"
+#define COMMAND_NOPERMISSION_STRING "Permission denied"
+#define BRCTL_EXPECT_STRING "bridge name"
+#define VLAN8021Q_CAT_ETH_EXPECT_STRING "REORDER_HDR:"
+#define VLAN8021Q_CONFIG_EXPECT_STRING "VLAN Dev name"
+
+#define IFACE_CONFIG_FILE_PREFIX_RH "/etc/sysconfig/network-scripts/ifcfg-"
+
+#define CONT_BUFF_SIZE 256
+
+/* the bridge seems have 0 value when it is up , so adjust the value,
+   and found out which are physical cards */
+static int host_iface_adjust(EthIface *piface)
+{
+    if (piface->eth_type == ETH_TYPE_BRIDGE) {
+        if (piface->run_prop.state == ETH_TYPE_UNKNOWN) {
+            piface->run_prop.state = ETH_STATE_UP;
+        }
+    }
+    if (1 == eth_iface_filter_peths(piface, NULL)) {
+        piface->eth_type = ETH_TYPE_PHYSICAL;
+    }
+    return 1;
+}
+
+int host_ifacelist_is_present_cmd(EthIfacesList *plist, int *retvalues,
+                                  int compare_name_only)
+{
+    EthIfacesList ifaces_list;
+    int retvalue;
+    int i, j;
+    eth_iface_filter_func func;
+
+    eth_ifaceslist_init(&ifaces_list);
+    retvalue = get_host_eth_ifaces_ip_addr(ifaces_list.pifaces,
+                 &ifaces_list.count, MAX_IFACE_NUM, NULL, NULL);
+    if (retvalue != 1) {
+        goto out;
+    }
+
+    if (compare_name_only == 0) {
+        func = eth_iface_filter_by_refname;
+    } else {
+        func = eth_iface_filter_by_ref;
+    }
+    i = 0;
+    while (i < plist->count) {
+        retvalues[i] = 0;
+        j = 0;
+        while (j < ifaces_list.count) {
+            if (1 == func(ifaces_list.pifaces[j], plist->pifaces[i])) {
+                retvalues[i] = 1;
+                break;
+            }
+            j++;
+        }
+        i++;
+    }
+
+ out:
+    eth_ifaceslist_uninit(&ifaces_list);
+    return retvalue;
+}
+
+static int host_iface_is_present_cmd(EthIface *piface)
+{
+    EthIface *pifaces[1];
+    int retvalue;
+    int ifaces_num;
+    int exist_flag = 0;
+    EthIface ref;
+    eth_iface_init(&ref);
+    ref.name = SAFE_STRDUP(piface->name);
+
+    retvalue = get_host_eth_ifaces_ip_addr(pifaces, &ifaces_num,
+                            1, eth_iface_filter_by_ref, &ref);
+
+    if ((retvalue == 1) && (ifaces_num == 1)) {
+        exist_flag = 1;
+    }
+    eth_ifaces_clear(pifaces, ifaces_num);
+    eth_iface_uninit(&ref);
+    return exist_flag;
+}
+
+static int host_br_is_present_cmd(EthIface *piface)
+{
+    EthIface *pifaces[1];
+    int retvalue;
+    int ifaces_num;
+    int exist_flag = 0;
+    EthIface ref;
+    eth_iface_init(&ref);
+    ref.name = SAFE_STRDUP(piface->name);
+
+    retvalue = get_host_eth_ifaces_brctl(pifaces, &ifaces_num,
+                            1, eth_iface_filter_by_ref, &ref);
+
+    if ((retvalue == 1) && (ifaces_num == 1)) {
+        exist_flag = 1;
+    }
+    eth_ifaces_clear(pifaces, ifaces_num);
+    eth_iface_uninit(&ref);
+    return exist_flag;
+}
+
+/* 1: the bridge have the iface attached
+   2: the iface is attached to other bridge
+   other: not found */
+int host_br_have_iface_attached_cmd(EthIface *pbr, EthIface *piface,
+                    EthIface **ppbr_result)
+{
+    int ret = 0;
+    BR_Prop *pbr_prop;
+    EthIface **pifaces = NULL;
+    int retvalue;
+    int ifaces_num = 0;
+    int i, j;
+
+    if (0 == host_iface_is_present_cmd(piface)) {
+        return -1;
+    }
+
+    SAFE_CALLOC(pifaces, MAX_IFACE_NUM, sizeof(EthIface *));
+
+    retvalue = get_host_eth_ifaces_brctl(pifaces, &ifaces_num,
+                            MAX_IFACE_NUM, NULL, NULL);
+
+    if ((retvalue == 1) && (ifaces_num > 0)) {
+        i = 0;
+        while (i < ifaces_num) {
+            if (0 == strcmp(pbr->name, pifaces[i]->name)) {
+                /* found the bridge */
+                pbr_prop = pifaces[i]->pbr_prop;
+                j = 0;
+                while (j < pbr_prop->port_num) {
+                    if (0 == strcmp(piface->name, pbr_prop->port_names[j])) {
+                        ret = 1;
+                        break;
+                    }
+                    j++;
+                }
+                if (ppbr_result != NULL) {
+                    *ppbr_result = pifaces[i];
+                    pifaces[i] = NULL;
+                }
+                goto out;
+            } else {
+               /* not the bridge */
+                pbr_prop = pifaces[i]->pbr_prop;
+                j = 0;
+                while (j < pbr_prop->port_num) {
+                    if (0 == strcmp(piface->name, pbr_prop->port_names[j])) {
+                        ret = 2;
+                        goto out;
+                    }
+                    j++;
+                }
+            }
+            i++;
+        }
+    } else {
+        ret = -2;
+    }
+
+ out:
+    if (pifaces != NULL) {
+        eth_ifaces_clear(pifaces, ifaces_num);
+        SAFE_FREE(pifaces);
+    }
+    return ret;
+}
+
+static int host_vlan_is_present_8021q_cmd(EthIface *piface)
+{
+    EthIface *pifaces[1];
+    int retvalue;
+    int ifaces_num;
+    int exist_flag = 0;
+    EthIface ref;
+    eth_iface_init(&ref);
+    ref.name = SAFE_STRDUP(piface->name);
+
+    retvalue = get_host_eth_ifaces_cat_vlan_config(pifaces, &ifaces_num,
+                            1, eth_iface_filter_by_ref, &ref);
+
+    if ((retvalue == 1) && (ifaces_num == 1)) {
+        exist_flag = 1;
+    }
+    eth_ifaces_clear(pifaces, ifaces_num);
+    eth_iface_uninit(&ref);
+    return exist_flag;
+}
+
+int get_host_eth_ifaces_ip_addr(EthIface **ppifaces, int *retnum, int maxnum,
+                eth_iface_filter_func filter_func, void *filter_opaque)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *buff = NULL;
+    int ret = 0;
+    EthIface tcard, **ppdest;
+    char *temp, *temp2, *temp3;
+    char *search_str;
+    int count = 0;
+    int filter_ret;
+    int line_count = 0;
+    struct in_addr addr;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    cmd[0] = '\0';
+    strcat(cmd, "ip addr");
+    stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    eth_iface_init(&tcard);
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CMD_DEBUG(3, "%s", buff);
+        if (line_count == 0) {
+            if (NULL != strstr(buff, COMMAND_NOTFOUND_STRING)) {
+                CU_DEBUG("Got [%s] with command [%s], check u environment.\n",
+                            COMMAND_NOTFOUND_STRING, cmd);
+                ret = ERR_COMMAND_NOT_SUPPORT;
+                goto out;
+            }
+            if (NULL != strstr(buff, COMMAND_NOPERMISSION_STRING)) {
+                CU_DEBUG("Got [%s] with command [%s], check u environment.\n",
+                            COMMAND_NOPERMISSION_STRING, cmd);
+                ret = ERR_COMMAND_NO_PERMISSION;
+                goto out;
+            }
+        }
+        line_count++;
+        /*analysis the output, example is something like following:
+
+3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc \
+pfifo_fast run_prop.state UP qlen 1000
+    link/ether 08:00:27:e3:13:f8 brd ff:ff:ff:ff:ff:ff
+    inet 10.0.3.15/24 brd 10.0.3.255 scope global eth1
+    inet6 fe80::a00:27ff:fee3:13f8/64 scope link
+       valid_lft forever preferred_lft forever
+4: eth1.5 at eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc \
+noqueue run_prop.state UP
+    link/ether 08:00:27:e3:13:f8 brd ff:ff:ff:ff:ff:ff
+    inet6 fe80::a00:27ff:fee3:13f8/64 scope link
+       valid_lft forever preferred_lft forever
+
+        */
+        /* for line that divide two devices */
+        if ((0 != strncmp(buff, " ", 1)) && (0 != strncmp(buff, "\t", 1))) {
+            if (tcard.name != NULL) {
+                /* device found, copy the content */
+                filter_ret = 1;
+                if (filter_func != NULL) {
+                    filter_ret = filter_func(&tcard, filter_opaque);
+                }
+                /* found a device match the requirement, put it to the list */
+                if (filter_ret == 1) {
+                    if (count >= maxnum) {
+                        ret = ERR_DEVICE_EXCEED_MAXNUM;
+                        goto out;
+                    }
+                    ppdest = ppifaces + count;
+                    SAFE_MALLOC(*ppdest, sizeof(EthIface));
+                    eth_iface_dup(*ppdest, &tcard);
+                    count++;
+                }
+            eth_iface_uninit(&tcard);
+            eth_iface_init(&tcard);
+            }
+            /* discovery names */
+            search_str = ": ";
+            temp = strstr(buff, search_str);
+            if (temp != NULL) {
+                temp += strlen(search_str);
+                temp2 = strstr(temp, search_str);
+                if (temp2 != NULL) {
+                    /* found string that contains names,
+                       start point is temp, end point is temp2 */
+                    search_str = "@";
+                    temp3 = strstr(temp, search_str);
+                    if ((temp3 != NULL) && (temp3 < temp2)) {
+                        /* have parent dev, temp3 holds the division */
+                        SAFE_FREE(tcard.dep_ifname);
+                        tcard.dep_ifname = strndup(temp3+1, temp2-temp3-1);
+                        SAFE_FREE(tcard.name);
+                        tcard.name = strndup(temp, temp3-temp);
+                    } else {
+                        SAFE_FREE(tcard.name);
+                        tcard.name = strndup(temp, temp2-temp);
+                    }
+                }
+            }
+            /* discovery run_prop.state */
+            search_str = "state ";
+            temp = strstr(buff, search_str);
+            if (temp != NULL) {
+                temp += strlen(search_str);
+                if (0 == strncmp(temp, "UP", 2)) {
+                    tcard.run_prop.state = ETH_STATE_UP;
+                } else if (0 == strncmp(temp, "DOWN", 4)) {
+                    tcard.run_prop.state = ETH_STATE_DOWN;
+                } else if (0 == strncmp(temp, "UNKNOWN", 7)) {
+                    tcard.run_prop.state = ETH_STATE_UNKNOWN;
+                }
+            }
+            continue;
+        }
+        /* for lines that saying other properties */
+        /* dicovering mac */
+        search_str = "ether ";
+        temp = strstr(buff, search_str);
+        if (temp != NULL) {
+            temp += strlen(search_str);
+            SAFE_FREE(tcard.mac);
+            tcard.mac = strtok_onetime(temp, " ");
+        }
+        /* dicovering ip and ip_mask for ipv4 */
+        search_str = "inet ";
+        temp = strstr(buff, search_str);
+        if (temp != NULL) {
+            temp += strlen(search_str);
+            temp2 = strstr(temp, "/");
+            if (temp2 != NULL) {
+                /* found the ip and mask, temp2 holds the division */
+                SAFE_FREE(tcard.ipv4_prop.ip);
+                tcard.ipv4_prop.ip = strndup(temp, temp2-temp);
+                if (1 == netmask_easy_to_inaddr(&addr, temp2+1)) {
+                    SAFE_FREE(tcard.ipv4_prop.ip_mask);
+                    SAFE_MALLOC(tcard.ipv4_prop.ip_mask, INET_ADDRSTRLEN);
+                    tcard.ipv4_prop.ip_mask[INET_ADDRSTRLEN-1] = '\0';
+                    if (NULL == inet_ntop(AF_INET, &addr,
+                                    tcard.ipv4_prop.ip_mask, INET_ADDRSTRLEN)) {
+                        SAFE_FREE(tcard.ipv4_prop.ip_mask);
+                    }
+                }
+            }
+        }
+    }
+
+    /* because the output have no indication about end, so need to try add
+       the latest device found to the list */
+    if (tcard.name != NULL) {
+        /* device found, copy the content */
+        filter_ret = 1;
+        if (filter_func != NULL) {
+            filter_ret = filter_func(&tcard, filter_opaque);
+        }
+        /* found a device match the requirement, put it to the list */
+        if (filter_ret == 1) {
+            if (count >= maxnum) {
+                ret = ERR_DEVICE_EXCEED_MAXNUM;
+                goto out;
+            }
+            ppdest = ppifaces + count;
+            SAFE_MALLOC(*ppdest, sizeof(EthIface));
+            eth_iface_dup(*ppdest, &tcard);
+            count++;
+        }
+    }
+
+    ret = 1;
+
+ out:
+    if (stream != NULL) {
+        pclose(stream);
+    }
+    eth_iface_uninit(&tcard);
+    SAFE_FREE(buff);
+    *retnum = count;
+
+    return ret;
+}
+
+int get_host_eth_ifaces_ifconfig(EthIface **ppifaces, int *retnum, int maxnum,
+                eth_iface_filter_func filter_func, void *filter_opaque)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *buff = NULL;
+    int ret = 0;
+    EthIface tcard, **ppdest;
+    char *temp, *temp2;
+    char *search_str;
+    int count = 0;
+    int filter_ret;
+    int line_count = 0;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    cmd[0] = '\0';
+    strcat(cmd,  "ifconfig");
+    stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    eth_iface_init(&tcard);
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CMD_DEBUG(3, "%s", buff);
+        if (line_count == 0) {
+            if (NULL != strstr(buff, COMMAND_NOTFOUND_STRING)) {
+                CU_DEBUG("Got [%s] with command [%s], check u environment.\n",
+                            COMMAND_NOTFOUND_STRING, cmd);
+                ret = ERR_COMMAND_NOT_SUPPORT;
+                goto out;
+            }
+            if (NULL != strstr(buff, COMMAND_NOPERMISSION_STRING)) {
+                CU_DEBUG("Got [%s] with command [%s], check u environment.\n",
+                            COMMAND_NOPERMISSION_STRING, cmd);
+                ret = ERR_COMMAND_NO_PERMISSION;
+                goto out;
+            }
+        }
+        line_count++;
+        /*analysis the output, example is something like following:
+
+eth1      Link encap:Ethernet  HWaddr 08:00:27:E3:13:F8
+          inet addr:10.0.3.15  Bcast:10.0.3.255  Mask:255.255.255.0
+          inet6 addr: fe80::a00:27ff:fee3:13f8/64 Scope:Link
+          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
+          RX packets:236 errors:0 dropped:0 overruns:0 frame:0
+          TX packets:346 errors:0 dropped:0 overruns:0 carrier:0
+          collisions:0 txqueuelen:1000
+          RX bytes:100464 (98.1 KiB)  TX bytes:30721 (30.0 KiB)
+
+eth1.5    Link encap:Ethernet  HWaddr 08:00:27:E3:13:F8
+          ...
+
+        */
+        /* for line that divide two devices */
+        if (0 == strncmp(buff, "\n", 1)) {
+            /* device found, copy the content */
+            filter_ret = 1;
+            if (filter_func != NULL) {
+                filter_ret = filter_func(&tcard, filter_opaque);
+            }
+            /* found a device match the requirement, put it to the list */
+            if (filter_ret == 1) {
+                if (count >= maxnum) {
+                    ret = ERR_DEVICE_EXCEED_MAXNUM;
+                    goto out;
+                }
+                ppdest = ppifaces + count;
+                SAFE_MALLOC(*ppdest, sizeof(EthIface));
+                eth_iface_dup(*ppdest, &tcard);
+                count++;
+            }
+            eth_iface_uninit(&tcard);
+            eth_iface_init(&tcard);
+            continue;
+        }
+        /* for line that saying other properties */
+        if (0 == strncmp(buff, " ", 1)) {
+            /* discovery ip for ip v4 */
+            search_str = "inet addr:";
+            temp = strstr(buff, search_str);
+            if (temp != NULL) {
+                temp += strlen(search_str);
+                SAFE_FREE(tcard.ipv4_prop.ip);
+                tcard.ipv4_prop.ip = strtok_onetime(temp, " ");
+                /* discovery ip mask*/
+                search_str = "Mask";
+                temp = strstr(buff, search_str);
+                if (temp != NULL) {
+                    temp += strlen(search_str);
+                    SAFE_FREE(tcard.ipv4_prop.ip_mask);
+                    tcard.ipv4_prop.ip_mask = strtok_onetime(temp, " ");
+                    if (tcard.ipv4_prop.ip_mask == NULL) {
+                        tcard.ipv4_prop.ip_mask = strtok_onetime(temp, "\n");
+                    }
+                }
+            }
+
+            /* discovery RX and TX bytes */
+            search_str = "RX bytes:";
+            temp = strstr(buff, search_str);
+            if (temp != NULL) {
+                temp += strlen(search_str);
+                tcard.run_prop.rx_bytes = strtoll(temp, &temp2, 10);
+                if (temp == temp2) {
+                    /*failed to get the value, restore it to default */
+                    tcard.run_prop.rx_bytes = NUM_NOT_GOT;
+                }
+                search_str = "TX bytes:";
+                temp = strstr(buff, search_str);
+                if (temp != NULL) {
+                    temp += strlen(search_str);
+                    tcard.run_prop.tx_bytes = strtoll(temp, &temp2, 10);
+                    if (temp == temp2) {
+                        /*failed to get the value, restore it to default */
+                        tcard.run_prop.tx_bytes = NUM_NOT_GOT;
+                    }
+                }
+            }
+        continue;
+        }
+        /* for lines that saying the device with title */
+        /* discovery name */
+        SAFE_FREE(tcard.name);
+        tcard.name = strtok_onetime(buff, " ");
+        /* discovery mac */
+        search_str = "HWaddr ";
+        temp = strstr(buff, search_str);
+        if (temp != NULL) {
+            temp += strlen(search_str);
+            SAFE_FREE(tcard.mac);
+            tcard.mac = strtok_onetime(temp, " ");
+            if (tcard.mac == NULL) {
+                tcard.mac = strtok_onetime(temp, "\n");
+            }
+        }
+        /* discovery type */
+        search_str = "Local Loopback";
+        temp = strstr(buff, search_str);
+        if (temp != NULL) {
+            tcard.eth_type = ETH_TYPE_LOOPBACK;
+        }
+        continue;
+    }
+
+    ret = 1;
+
+ out:
+    if (stream != NULL) {
+        pclose(stream);
+    }
+    eth_iface_uninit(&tcard);
+    SAFE_FREE(buff);
+    *retnum = count;
+
+    return ret;
+}
+
+int get_host_eth_ifaces_brctl(EthIface **ppifaces, int *retnum, int maxnum,
+                eth_iface_filter_func filter_func, void *filter_opaque)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *buff = NULL;
+    int ret = 0;
+    EthIface tcard, **ppdest;
+    BR_Prop tbr;
+    char *last = NULL, *iter;
+    char *char_stp = NULL;
+    char *port_name = NULL;
+    int count = 0;
+    int filter_ret;
+    int line_count = 0;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    cmd[0] = '\0';
+    strcat(cmd, "brctl show");
+    stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    eth_iface_init(&tcard);
+    br_prop_init(&tbr);
+    tbr.port_num = 0;
+    port_name = NULL;
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CMD_DEBUG(3, "%s", buff);
+/* output string should be something like following
+
+bridge name     bridge id               STP enabled     interfaces
+testbr          8000.000000000000       no
+virbr0          8000.5254004ac14c       yes             virbr0-nic
+                                                        vnet0
+virbr3          8000.5254004ac16c       yes             virbr3-nic
+...
+*/
+        if (line_count == 0) {
+            if (NULL == strstr(buff, BRCTL_EXPECT_STRING)) {
+                CU_DEBUG("[%s] not found with command [%s],"
+                            "check u environment.\n",
+                            BRCTL_EXPECT_STRING, cmd);
+                ret = ERR_COMMAND_NOT_SUPPORT;
+                goto out;
+            }
+            line_count++;
+            continue;
+        }
+        if ((buff[0] == ' ') || (buff[0] == '\t')) {
+            /* the line saying ifaces it attached */
+            port_name = strtok_r(buff, "\n", &last);
+            if (port_name == NULL) {
+                CU_DEBUG("command [%s] did not output as expected.", cmd);
+                continue;
+            }
+            port_name = strtok_r(buff, "\t", &last);
+            if (port_name == NULL) {
+                CU_DEBUG("command [%s] did not output as expected.", cmd);
+                continue;
+            }
+            /* adding the port */
+            if (tbr.port_names == NULL) {
+                SAFE_CALLOC(tbr.port_names, MAX_IFACE_NUM, sizeof(char *));
+                tbr.port_num = 0;
+            }
+            if (tbr.port_num >= MAX_IFACE_NUM) {
+                CU_DEBUG("bridge [%s] have too much eth attached!",
+                        tcard.name);
+                ret = ERR_DEVICE_EXCEED_MAXNUM;
+                goto out;
+            }
+            tbr.port_names[tbr.port_num] = SAFE_STRDUP(port_name);
+            tbr.port_num++;
+        } else {
+            /* the line saying a new bridge */
+            if (tcard.name != NULL) {
+                /* have a valid iface, so add it to the list */
+                tcard.pbr_prop = &tbr;
+                tcard.eth_type = ETH_TYPE_BRIDGE;
+                filter_ret = 1;
+                if (filter_func != NULL) {
+                    filter_ret = filter_func(&tcard, filter_opaque);
+                }
+                /* found a device match the requirement, put it to the list */
+                if (filter_ret == 1) {
+                    if (count >= maxnum) {
+                        CU_DEBUG("too much bridge found, max is %d",
+                                maxnum);
+                        ret = ERR_DEVICE_EXCEED_MAXNUM;
+                        goto out;
+                    }
+                    ppdest = ppifaces + count;
+                    SAFE_MALLOC(*ppdest, sizeof(EthIface));
+                    eth_iface_dup(*ppdest, &tcard);
+                    count++;
+                }
+                tcard.pbr_prop = NULL;
+                eth_iface_uninit(&tcard);
+                eth_iface_init(&tcard);
+                br_prop_uninit(&tbr);
+                br_prop_init(&tbr);
+                tbr.port_num = 0;
+            }
+            SAFE_STRDUP_WITH_FUNC(tcard.name,
+                                    strtok_r(buff, "\t", &last), iter);
+            SAFE_STRDUP_WITH_FUNC(tbr.bridge_id,
+                                    strtok_r(NULL, "\t", &last), iter);
+            char_stp = strtok_r(NULL, "\t", &last);
+            if (char_stp != NULL) {
+                if (0 == strcmp(char_stp, "yes")) {
+                    tbr.STP = 1;
+                } else if (0 == strcmp(char_stp, "no")) {
+                    tbr.STP = 0;
+                }
+            }
+            if (last != NULL) {
+                if ((*last == '\0') || (*(last+1) == '\0')) {
+                    CU_DEBUG("command [%s] did not output as expected,"
+                            "string left [%s].", cmd, last);
+                    continue;
+                }
+                last++;
+            }
+            if (*last == '\t') {
+                port_name = NULL;
+            } else {
+                port_name = strtok_r(NULL, "\n", &last);
+                if (port_name != NULL) {
+                    /* adding the port */
+                    if (tbr.port_names == NULL) {
+                        SAFE_CALLOC(tbr.port_names,
+                                MAX_IFACE_NUM, sizeof(char *));
+                        tbr.port_num = 0;
+                    }
+                    if (tbr.port_num >= MAX_IFACE_NUM) {
+                        CU_DEBUG("bridge [%s] have too much eth attached!",
+                                tcard.name);
+                        ret = ERR_DEVICE_EXCEED_MAXNUM;
+                        goto out;
+                    }
+                    tbr.port_names[tbr.port_num] = SAFE_STRDUP(port_name);
+                    tbr.port_num++;
+                }
+            }
+        }
+        line_count++;
+    }
+
+    if (tcard.name != NULL) {
+        /* have a valid iface, so add it to the list */
+        tcard.pbr_prop = &tbr;
+        tcard.eth_type = ETH_TYPE_BRIDGE;
+        filter_ret = 1;
+        if (filter_func != NULL) {
+            filter_ret = filter_func(&tcard, filter_opaque);
+        }
+        /* found a device match the requirement, put it to the list */
+        if (filter_ret == 1) {
+            if (count >= maxnum) {
+                CU_DEBUG("too much bridge found, max is %d",
+                        maxnum);
+                ret = ERR_DEVICE_EXCEED_MAXNUM;
+                goto out;
+            }
+            ppdest = ppifaces + count;
+            SAFE_MALLOC(*ppdest, sizeof(EthIface));
+            eth_iface_dup(*ppdest, &tcard);
+            count++;
+        }
+        tcard.pbr_prop = NULL;
+    }
+
+    ret = 1;
+
+ out:
+    if (stream != NULL) {
+        pclose(stream);
+    }
+    br_prop_uninit(&tbr);
+    eth_iface_uninit(&tcard);
+    SAFE_FREE(buff);
+    *retnum = count;
+
+    return ret;
+}
+
+static int get_iface_cat_vlan_one_eth_8021q(EthIface *piface)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *cmd_prefix = "cat /proc/net/vlan/";
+    char *buff = NULL;
+    VLAN_Prop_8021q *pprop_8021q;
+    char *last = NULL;
+    char *char_temp = NULL;
+    char *search_str, *iter, *temp1, *temp2, *temp3, *qos;
+    int ret = 0;
+    int line_count = -1;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if ((piface->name == NULL) ||
+        ((strlen(piface->name)+strlen(cmd_prefix)) > (sizeof(cmd)-1))) {
+        CU_DEBUG("error in building up cmd line, name is %s.", piface->name);
+        ret = ERR_COMMAND_NO_READY;
+        goto out;
+    }
+    memcpy(cmd, cmd_prefix, strlen(cmd_prefix)+1);
+    strcat(cmd, piface->name);
+
+    stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    if (piface->pvlan_prop == NULL) {
+        SAFE_MALLOC(piface->pvlan_prop, sizeof(VLAN_Prop));
+        vlan_prop_init(piface->pvlan_prop, VLAN_TYPE_802_1_Q);
+    }
+    if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) {
+        ret = 0;
+        goto out;
+    }
+    pprop_8021q = &(piface->pvlan_prop->props.prop_8021q);
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        line_count++;
+        CMD_DEBUG(3, "%s", buff);
+/* output is expected some thing like following
+eth1.7.7  VID: 7         REORDER_HDR: 1  dev->priv_flags: 1
+         total frames received            0
+          total bytes received            0
+      Broadcast/Multicast Rcvd            0
+
+      total frames transmitted            0
+       total bytes transmitted            0
+            total headroom inc            0
+           total encap on xmit            0
+Device: eth1.7
+INGRESS priority mappings: 0:0  1:0  2:0  3:0  4:0  5:0  6:0 7:0
+ EGRESS priority mappings:
+*/
+        if (line_count == 0) {
+            if (NULL == strstr(buff, VLAN8021Q_CAT_ETH_EXPECT_STRING)) {
+                CU_DEBUG("[%s] not found with command [%s],"
+                            "check u environment.\n",
+                            VLAN8021Q_CAT_ETH_EXPECT_STRING, cmd);
+                ret = ERR_COMMAND_NOT_SUPPORT;
+                goto out;
+            }
+        }
+        search_str = "VID: ";
+        temp1 = strstr(buff, search_str);
+        if (temp1 != NULL) {
+            /* first line */
+            temp1 += strlen(search_str);
+            search_str = "REORDER_HDR: ";
+            temp2 = strstr(buff, search_str);
+            if (temp2 != NULL) {
+                temp2 += strlen(search_str);
+            }
+            search_str = "priv_flags: ";
+            temp3 = strstr(buff, search_str);
+            if (temp3 != NULL) {
+                temp3 += strlen(search_str);
+            }
+            if ((temp2 != NULL) && (temp3 != NULL)) {
+                char_temp = strtok_r(temp1, " ", &last);
+                if (char_temp != NULL) {
+                    pprop_8021q->vlan_id = strtol(char_temp, &iter, 10);
+                }
+                char_temp = strtok_r(temp2, " ", &last);
+                if (char_temp != NULL) {
+                    pprop_8021q->reorder_hdr = strtol(char_temp, &iter, 10);
+                }
+                char_temp = strtok_r(temp3, " ", &last);
+                if (char_temp != NULL) {
+                    pprop_8021q->priv_flag = strtol(char_temp, &iter, 10);
+                }
+            }
+            continue;
+        }
+        search_str = "total bytes received";
+        temp1 = strstr(buff, search_str);
+        if (temp1 != NULL) {
+            temp1 += strlen(search_str);
+            char_temp = strtok_r(temp1, " ", &last);
+            if (char_temp != NULL) {
+                piface->run_prop.rx_bytes = strtoll(char_temp, &iter, 10);
+            }
+            continue;
+        }
+        search_str = "total bytes transmitted";
+        temp1 = strstr(buff, search_str);
+        if (temp1 != NULL) {
+            temp1 += strlen(search_str);
+            char_temp = strtok_r(temp1, " ", &last);
+            if (char_temp != NULL) {
+                piface->run_prop.tx_bytes = strtoll(char_temp, &iter, 10);
+            }
+            continue;
+        }
+        search_str = "Device: ";
+        temp1 = strstr(buff, search_str);
+        if (temp1 != NULL) {
+            temp1 += strlen(search_str);
+            pprop_8021q->parent = strtok_onetime(temp1, " ");
+            if (pprop_8021q->parent == NULL) {
+                pprop_8021q->parent = strtok_onetime(temp1, "\n");
+            }
+            continue;
+        }
+        search_str = "INGRESS priority mappings: ";
+        temp1 = strstr(buff, search_str);
+        if (temp1 != NULL) {
+            temp1 += strlen(search_str);
+            if (NULL != strstr(temp1, ":")) {
+                qos = strtok_onetime(temp1, "\n");
+                if (qos != NULL) {
+                    vlan_8021q_qos_str_to_num(&(pprop_8021q->ingress), qos);
+                    SAFE_FREE(qos);
+                }
+            }
+            continue;
+        }
+        search_str = "EGRESS priority mappings: ";
+        temp1 = strstr(buff, search_str);
+        if (temp1 != NULL) {
+            temp1 += strlen(search_str);
+            if (NULL != strstr(temp1, ":")) {
+                qos = strtok_onetime(temp1, "\n");
+                if (qos != NULL) {
+                    vlan_8021q_qos_str_to_num(&(pprop_8021q->egress), qos);
+                    SAFE_FREE(qos);
+                }
+            }
+            continue;
+        }
+    }
+    piface->eth_type = ETH_TYPE_VLAN;
+    ret = 1;
+
+ out:
+    if (stream != NULL) {
+        pclose(stream);
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int get_host_eth_ifaces_cat_vlan_config(EthIface **ppifaces, int *retnum,
+            int maxnum, eth_iface_filter_func filter_func, void *filter_opaque)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *buff = NULL;
+    int ret = 0;
+    EthIface tcard, **ppdest;
+    VLAN_Prop tvlan;
+    int count = 0;
+    int filter_ret;
+    int line_count = -1;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    cmd[0] = '\0';
+    strcat(cmd, "cat /proc/net/vlan/config");
+    stream = pipe_excute_command_type_read(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    eth_iface_init(&tcard);
+    vlan_prop_init(&tvlan, VLAN_TYPE_802_1_Q);
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        line_count++;
+        CMD_DEBUG(3, "%s", buff);
+/* output string should be something like following
+
+VLAN Dev name    | VLAN ID
+Name-Type: VLAN_NAME_TYPE_RAW_PLUS_VID_NO_PAD
+eth1.5         | 5  | eth1
+...
+*/
+        if (line_count == 0) {
+            if (NULL == strstr(buff, VLAN8021Q_CONFIG_EXPECT_STRING)) {
+                CU_DEBUG("[%s] not found with command [%s],"
+                            "check u environment.\n",
+                            VLAN8021Q_CONFIG_EXPECT_STRING, cmd);
+                ret = ERR_COMMAND_NOT_SUPPORT;
+                goto out;
+            }
+            continue;
+        }
+        if (line_count < 2) {
+            continue;
+        }
+
+        /* the line saying a new bridge */
+        if (tcard.name != NULL) {
+            /* have a valid iface, so add it to the list */
+            tcard.pvlan_prop = &tvlan;
+            /* get additional information for this vlan */
+            get_iface_cat_vlan_one_eth_8021q(&tcard);
+            /* filt it */
+            filter_ret = 1;
+            if (filter_func != NULL) {
+                filter_ret = filter_func(&tcard, filter_opaque);
+            }
+            /* found a device match the requirement, put it to the list */
+            if (filter_ret == 1) {
+                if (count >= maxnum) {
+                    CU_DEBUG("too much vlan found, max is %d",
+                            maxnum);
+                    ret = ERR_DEVICE_EXCEED_MAXNUM;
+                    goto out;
+                }
+                ppdest = ppifaces + count;
+                SAFE_MALLOC(*ppdest, sizeof(EthIface));
+                eth_iface_dup(*ppdest, &tcard);
+                count++;
+            }
+            tcard.pvlan_prop = NULL;
+            eth_iface_uninit(&tcard);
+            eth_iface_init(&tcard);
+            vlan_prop_uninit(&tvlan);
+            vlan_prop_init(&tvlan, VLAN_TYPE_802_1_Q);
+        }
+        /* get the name, other properties would be got in special file */
+        tcard.name = strtok_onetime(buff, " ");
+    }
+
+    if (tcard.name != NULL) {
+        /* have a valid iface, so add it to the list */
+        tcard.pvlan_prop = &tvlan;
+        /* get additional information for this vlan */
+        get_iface_cat_vlan_one_eth_8021q(&tcard);
+        /* filt it */
+        filter_ret = 1;
+        if (filter_func != NULL) {
+            filter_ret = filter_func(&tcard, filter_opaque);
+        }
+        /* found a device match the requirement, put it to the list */
+        if (filter_ret == 1) {
+            if (count >= maxnum) {
+                CU_DEBUG("too much vlan found, max is %d",
+                        maxnum);
+                ret = ERR_DEVICE_EXCEED_MAXNUM;
+                goto out;
+            }
+            ppdest = ppifaces + count;
+            SAFE_MALLOC(*ppdest, sizeof(EthIface));
+            eth_iface_dup(*ppdest, &tcard);
+            count++;
+        }
+        tcard.pvlan_prop = NULL;
+    }
+
+    ret = 1;
+
+ out:
+    if (stream != NULL) {
+        pclose(stream);
+    }
+    vlan_prop_uninit(&tvlan);
+    eth_iface_uninit(&tcard);
+    SAFE_FREE(buff);
+    *retnum = count;
+
+    return ret;
+}
+
+int change_state_host_iface_cmd(EthIface *piface, int state)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *cmd_prefix = "ifconfig ";
+    char *cmd_suffix = NULL;
+    char *buff = NULL;
+    int ret = 0;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if (state == ETH_STATE_UP) {
+        cmd_suffix = " up";
+    } else if (state == ETH_STATE_DOWN) {
+        cmd_suffix = " down";
+    }
+
+    if (cmd_suffix == NULL) {
+        CU_DEBUG("state change have not target state set.");
+        goto out;
+    }
+
+    if (piface->name == NULL) {
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        CU_DEBUG("bridge name not set, direct goto out.");
+        goto out;
+    }
+
+    if (0 == host_iface_is_present_cmd(piface)) {
+        CU_DEBUG("iface %s do not exist, can't change state.", piface->name);
+        ret = ERR_DEVICE_NOT_EXIST;
+        goto out;
+    }
+
+    if ((strlen(cmd_prefix)+strlen(piface->name)+strlen(cmd_suffix))
+                                                     > (sizeof(cmd)-1)) {
+        CU_DEBUG("error in building up cmd line, name is %s.", piface->name);
+        ret = ERR_COMMAND_NO_READY;
+        goto out;
+    }
+    snprintf(cmd, sizeof(cmd), "%s%s%s", cmd_prefix, piface->name, cmd_suffix);
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_NOT_SUPPORT;
+        goto out;
+    }
+
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int add_host_br_cmd(EthIface *piface, int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *cmd_prefix = "brctl addbr ";
+    char *path;
+    char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH;
+    char *cont, *c_stp;
+    char *buff = NULL;
+    int ret = 0;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if (piface->name == NULL) {
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        CU_DEBUG("bridge name not set, direct goto out.");
+        goto out;
+    }
+
+    if (1 == host_iface_is_present_cmd(piface)) {
+        CU_DEBUG("%s already exist, cann't create it as bridge.", piface->name);
+        ret = ERR_DEVICE_EXIST;
+        goto out;
+    }
+
+    if ((strlen(cmd_prefix)+strlen(piface->name)) > (sizeof(cmd)-1)) {
+        CU_DEBUG("error in building up cmd line, name is %s.", piface->name);
+        ret = ERR_COMMAND_NO_READY;
+        goto out;
+    }
+    snprintf(cmd, sizeof(cmd), "%s%s", cmd_prefix, piface->name);
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    if ((piface->pbr_prop != NULL) &&
+        (piface->pbr_prop->STP == 1)) {
+        c_stp = "on";
+        if (stream != NULL) {
+            pclose(stream);
+            stream = NULL;
+        }
+        cmd_prefix = "brctl stp ";
+        if ((strlen(cmd_prefix)+strlen(piface->name)
+                    +strlen(c_stp)) > (sizeof(cmd)-2)) {
+            CU_DEBUG("error in building up cmd line, name is %s.",
+                        piface->name);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+        }
+        snprintf(cmd, sizeof(cmd), "%s%s %s", cmd_prefix, piface->name, c_stp);
+        stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+        if (stream == NULL) {
+            goto out;
+        }
+        while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+            CU_DEBUG("get exception: %s", buff);
+            ret = ERR_COMMAND_EXECUTION;
+            goto out;
+        }
+    } else {
+        c_stp = "off";
+    }
+
+    if (persist_flag == 1) {
+        if (LINUX_REDHAT != get_host_linux_version()) {
+            ret = ERR_PERSIST_NOT_REDHAT;
+            CU_DEBUG("Host is not a RedHat version, return is %d",
+                        get_host_linux_version());
+            goto out;
+        }
+        path = combine_file_name(path_prefix, piface->name);
+        SAFE_CALLOC(cont, 1024, sizeof(char));
+        cont[1023] = 1;
+        snprintf(cont, 1024,
+                "DEVICE=%s\nTYPE=Bridge\nBOOTPROTO=dhcp\n"
+                "ONBOOT=yes\nDELAY=0\nSTP=%s\n",
+                piface->name, c_stp);
+        if (cont[1023] == '\0') {
+            CU_DEBUG("failed to build up contents, check the parameter.");
+            ret = ERR_FILE_CONT_TOO_LARGE;
+            SAFE_FREE(path);
+            SAFE_FREE(cont);
+            goto out;
+        }
+        ret = configure_file_update(path, cont);
+        SAFE_FREE(path);
+        SAFE_FREE(cont);
+        if (ret != 1) {
+            goto out;
+        }
+
+    }
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int del_host_br_cmd(EthIface *piface, int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *cmd_prefix = "brctl delbr ";
+    char *path;
+    char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH;
+    char *buff = NULL;
+    int ret = 0;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if (piface->name == NULL) {
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        CU_DEBUG("bridge name not set, direct goto out.");
+        goto out;
+    }
+
+    if (persist_flag == 1) {
+        if (LINUX_REDHAT != get_host_linux_version()) {
+            ret = ERR_PERSIST_NOT_REDHAT;
+            CU_DEBUG("Host is not a RedHat version, return is %d",
+                        get_host_linux_version());
+            goto out;
+        }
+        path = combine_file_name(path_prefix, piface->name);
+        ret = configure_file_remove(path);
+        SAFE_FREE(path);
+        if (ret != 1) {
+            goto out;
+        }
+    }
+
+    if (0 == host_br_is_present_cmd(piface)) {
+        CU_DEBUG("bridge %s do not exist, can't delete it.", piface->name);
+        ret = ERR_DEVICE_NOT_EXIST;
+        goto out;
+    }
+
+    if ((strlen(cmd_prefix)+strlen(piface->name)) > (sizeof(cmd)-1)) {
+        CU_DEBUG("error in building up cmd line, name is %s.", piface->name);
+        ret = ERR_COMMAND_NO_READY;
+        goto out;
+    }
+    snprintf(cmd, sizeof(cmd), "%s%s", cmd_prefix, piface->name);
+
+    /* bring down the iface */
+    change_state_host_iface_cmd(piface, ETH_STATE_DOWN);
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int mod_host_br_cmd(EthIface *piface, int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *cmd_prefix = "brctl stp ";
+    char *path;
+    char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH;
+    char *c_stp;
+    char *buff = NULL;
+    int ret = 0;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if (piface->name == NULL) {
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        CU_DEBUG("bridge name not set, direct goto out.");
+        goto out;
+    }
+
+    if (0 == host_br_is_present_cmd(piface)) {
+        CU_DEBUG("bridge %s do not exist, cann't modify it.", piface->name);
+        ret = ERR_DEVICE_EXIST;
+        goto out;
+    }
+
+    if ((piface->pbr_prop != NULL) &&
+            (piface->pbr_prop->STP == 1)) {
+        c_stp = "on";
+    } else {
+        c_stp = "off";
+    }
+
+    if ((strlen(cmd_prefix)+strlen(piface->name)
+                +strlen(c_stp)) > (sizeof(cmd)-2)) {
+        CU_DEBUG("error in building up cmd line, name is %s.", piface->name);
+        ret = ERR_COMMAND_NO_READY;
+        goto out;
+    }
+    snprintf(cmd, sizeof(cmd), "%s%s %s", cmd_prefix, piface->name, c_stp);
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    if (persist_flag == 1) {
+        if (LINUX_REDHAT != get_host_linux_version()) {
+            ret = ERR_PERSIST_NOT_REDHAT;
+            CU_DEBUG("Host is not a RedHat version, return is %d",
+                        get_host_linux_version());
+            goto out;
+        }
+        path = combine_file_name(path_prefix, piface->name);
+        ret = configure_file_replace_attr(path, "STP=", c_stp);
+        SAFE_FREE(path);
+        if (ret != 1) {
+            CU_DEBUG("error happened in persisting file.");
+            goto out;
+        }
+    }
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+static int append_vlan_8021q_parameters(char *cmd, int cmd_size,
+                                        VLAN_Prop_8021q *p_8021q)
+{
+    char *reorder = NULL;
+    char *egress = NULL, *ingress = NULL;
+    char *cmd_prefix;
+    int ret = 0;
+
+    if (p_8021q->reorder_hdr == 1) {
+        reorder = " reorder_hdr on";
+    } else if (p_8021q->reorder_hdr == 0) {
+        reorder = " reorder_hdr off";
+    }
+    if (reorder != NULL) {
+        if ((strlen(reorder)+strlen(cmd)) < (cmd_size-1)) {
+            strcat(cmd, reorder);
+        } else {
+            CU_DEBUG("cmd line too long, it is [%s]+[%s].", cmd, reorder);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+        }
+    }
+
+    vlan_8021q_qos_num_to_str(&ingress, &(p_8021q->ingress));
+    if (ingress != NULL) {
+        cmd_prefix = " ingress-qos-map ";
+        if ((strlen(ingress)+strlen(cmd)+strlen(cmd_prefix)) < (cmd_size-1)) {
+            strcat(cmd, cmd_prefix);
+            strcat(cmd, ingress);
+        } else {
+            CU_DEBUG("cmd line too long, it is [%s]+[%s]+[%s].",
+                        cmd, cmd_prefix, ingress);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+        }
+    }
+
+    vlan_8021q_qos_num_to_str(&egress, &(p_8021q->egress));
+    if (egress != NULL) {
+        cmd_prefix = " egress-qos-map ";
+        if ((strlen(egress)+strlen(cmd)+strlen(cmd_prefix)) < (cmd_size-1)) {
+            strcat(cmd, cmd_prefix);
+            strcat(cmd, egress);
+        } else {
+            CU_DEBUG("cmd line too long, it is [%s]+[%s]+[%s].",
+                        cmd, cmd_prefix, egress);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+        }
+    }
+
+    ret = 1;
+
+ out:
+    SAFE_FREE(ingress);
+    SAFE_FREE(egress);
+    return ret;
+}
+
+int add_host_vlan_8021q_cmd(EthIface *piface, int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[192];
+    char *path;
+    char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH;
+    char *cont;
+    char *buff = NULL;
+    int ret = 0;
+    int str_size;
+    EthIface iface;
+    VLAN_Prop_8021q *p_8021q;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    eth_iface_init(&iface);
+    if (piface->pvlan_prop == NULL) {
+        CU_DEBUG("pvlan_prop not set, direct goto out.");
+        goto out;
+    }
+    if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) {
+        CU_DEBUG("not a 802.1.q vlan, direct goto out.");
+        goto out;
+    }
+    p_8021q = &(piface->pvlan_prop->props.prop_8021q);
+    if ((p_8021q->vlan_id < 1) || (p_8021q->vlan_id > 4095)) {
+        CU_DEBUG("vlan_id for 802.1.q must be 0-4095, "
+                "and 0 is kept by system, request is %d.", p_8021q->vlan_id);
+        goto out;
+    }
+    if ((p_8021q->parent == NULL)) {
+        CU_DEBUG("creation of vlan iface for 802.1.q need parent iface set");
+        goto out;
+    }
+    iface.name = p_8021q->parent;
+    if (0 == host_iface_is_present_cmd(&iface)) {
+        CU_DEBUG("iface %s do not exist, cann't use it as parent iface.",
+                            iface.name);
+        iface.name = NULL;
+        ret = ERR_DEVICE_NOT_EXIST;
+        goto out;
+    }
+
+    /* restrict the iface name to ethx.x, so the name would be combined here */
+    str_size = strlen(p_8021q->parent)+6;
+    SAFE_MALLOC(iface.name, str_size);
+    snprintf(iface.name, str_size, "%s.%d",
+                p_8021q->parent, p_8021q->vlan_id);
+    if (1 == host_iface_is_present_cmd(&iface)) {
+        CU_DEBUG("iface %s already exist, cann't create it as a 802.1.q vlan.",
+                            iface.name);
+        ret = ERR_DEVICE_EXIST;
+        goto out;
+    }
+
+    /* building up command line */
+    cmd[sizeof(cmd)-1] = 1;
+    snprintf(cmd, sizeof(cmd), "ip link add link %s name %s type vlan id %d",
+            p_8021q->parent, iface.name, p_8021q->vlan_id);
+    if (cmd[sizeof(cmd)-1] == '\0') {
+            CU_DEBUG("cmd line too long, it is [%s].", cmd);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+    }
+
+    ret = append_vlan_8021q_parameters(cmd, sizeof(cmd), p_8021q);
+    if (ret != 1) {
+        goto out;
+    }
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    if (persist_flag == 1) {
+        if (LINUX_REDHAT != get_host_linux_version()) {
+            ret = ERR_PERSIST_NOT_REDHAT;
+            CU_DEBUG("Host is not a RedHat version, return is %d",
+                        get_host_linux_version());
+            goto out;
+        }
+        path = combine_file_name(path_prefix, iface.name);
+        SAFE_CALLOC(cont, 1024, sizeof(char));
+        cont[1023] = 1;
+        snprintf(cont, 1024,
+        "DEVICE=%s\nPEERDNS=yes\nVLAN=yes\n", iface.name);
+        if (cont[1023] == '\0') {
+            CU_DEBUG("failed to build up contents, check the parameter.");
+            ret = ERR_FILE_CONT_TOO_LARGE;
+            SAFE_FREE(path);
+            SAFE_FREE(cont);
+            goto out;
+        }
+        ret = configure_file_update(path, cont);
+        SAFE_FREE(path);
+        SAFE_FREE(cont);
+        if (ret != 1) {
+            goto out;
+        }
+    }
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    eth_iface_uninit(&iface);
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int del_host_vlan_8021q_cmd(EthIface *piface, int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[128];
+    char *path;
+    char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH;
+    char *buff = NULL;
+    int ret = 0;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if (piface->name == NULL) {
+        CU_DEBUG("piface name was not set, direct goto out.");
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        goto out;
+    }
+
+    if (persist_flag == 1) {
+        if (LINUX_REDHAT != get_host_linux_version()) {
+            ret = ERR_PERSIST_NOT_REDHAT;
+            CU_DEBUG("Host is not a RedHat version, return is %d",
+                        get_host_linux_version());
+            goto out;
+        }
+        path = combine_file_name(path_prefix, piface->name);
+        ret = configure_file_remove(path);
+        SAFE_FREE(path);
+        if (ret != 1) {
+            goto out;
+        }
+    }
+
+    if (piface->pvlan_prop == NULL) {
+        CU_DEBUG("pvlan_prop not set, direct goto out.");
+        goto out;
+    }
+    if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) {
+        CU_DEBUG("not a 802.1.q vlan, direct goto out.");
+        goto out;
+    }
+
+    if (0 == host_vlan_is_present_8021q_cmd(piface)) {
+        CU_DEBUG("vlan %s do not exist, cann't delete it.", piface->name);
+        ret = ERR_DEVICE_EXIST;
+        goto out;
+    }
+
+    /* building up command line */
+    cmd[sizeof(cmd)-1] = 1;
+    snprintf(cmd, sizeof(cmd), "ip link del %s", piface->name);
+    if (cmd[sizeof(cmd)-1] == '\0') {
+            CU_DEBUG("cmd line too long, it is [%s].", cmd);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+    }
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        ret = ERR_COMMAND_PIPE_ERR;
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int mod_host_vlan_8021q_cmd(EthIface *piface, int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[192];
+    char *buff = NULL;
+    int ret = 0;
+    VLAN_Prop_8021q *p_8021q;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if (piface->name == NULL) {
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        CU_DEBUG("piface name was not set, direct goto out.");
+        goto out;
+    }
+    if (piface->pvlan_prop == NULL) {
+        CU_DEBUG("pvlan_prop not set, direct goto out.");
+        goto out;
+    }
+    if (piface->pvlan_prop->vlan_type != VLAN_TYPE_802_1_Q) {
+        CU_DEBUG("not a 802.1.q vlan, direct goto out.");
+        goto out;
+    }
+    if (0 == host_vlan_is_present_8021q_cmd(piface)) {
+        CU_DEBUG("vlan %s do not exist, cann't modify it.", piface->name);
+        ret = ERR_DEVICE_EXIST;
+        goto out;
+    }
+    p_8021q = &(piface->pvlan_prop->props.prop_8021q);
+
+    /* building up command line */
+    cmd[sizeof(cmd)-1] = 1;
+    snprintf(cmd, sizeof(cmd), "ip link set %s type vlan",
+                        piface->name);
+    if (cmd[sizeof(cmd)-1] == '\0') {
+            CU_DEBUG("cmd line too long, it is [%s].", cmd);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+    }
+
+    ret = append_vlan_8021q_parameters(cmd, sizeof(cmd), p_8021q);
+    if (ret != 1) {
+        goto out;
+    }
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    if (persist_flag == 1) {
+        /* modification is logged by linux system itself in /proc/net/vlan */
+    }
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int add_host_iface_to_br_cmd(EthIface *piface, EthIface *pbr,
+                                    int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *buff = NULL;
+    int ret = 0;
+    int check_value;
+    char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH;
+    char *path;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if ((piface->name == NULL) || (pbr->name == NULL)) {
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        CU_DEBUG("name was not set, direct goto out.");
+        goto out;
+    }
+
+    check_value = host_br_have_iface_attached_cmd(pbr, piface, NULL);
+    if (check_value < 0) {
+        CU_DEBUG("iface %s or bridge %s do not exist, direct goto out.",
+                        piface->name, pbr->name);
+        ret = ERR_DEVICE_NOT_EXIST;
+        goto out;
+    } else if (check_value == 1) {
+        CU_DEBUG("iface %s already attached to bridge %s, can't do it again.",
+                        piface->name, pbr->name);
+        ret = ERR_DEVICE_ALREADY_DONE;
+        goto out;
+    } else if (check_value == 2) {
+        CU_DEBUG("iface %s is attached to another bridge, "
+                 "can't direct change it.",
+                 piface->name);
+        ret = ERR_DEVICE_CONNECT_OTHER;
+        goto out;
+    }
+
+    /* building up command line */
+    cmd[sizeof(cmd)-1] = 1;
+    snprintf(cmd, sizeof(cmd), "brctl addif %s %s",
+                        pbr->name, piface->name);
+    if (cmd[sizeof(cmd)-1] == '\0') {
+            CU_DEBUG("cmd line too long, it is [%s].", cmd);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+    }
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    if (persist_flag == 1) {
+        /* if the configuration file do not exist, would not create it */
+        if (LINUX_REDHAT != get_host_linux_version()) {
+            ret = ERR_PERSIST_NOT_REDHAT;
+            CU_DEBUG("Host is not a RedHat version, return is %d",
+                        get_host_linux_version());
+            goto out;
+        }
+        path = combine_file_name(path_prefix, piface->name);
+        ret = configure_file_replace_attr(path, "BRIDGE=", pbr->name);
+        SAFE_FREE(path);
+        if (ret != 1) {
+            CU_DEBUG("error happened in persisting file.");
+            goto out;
+        }
+    }
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+int remove_host_iface_from_br_cmd(EthIface *piface, EthIface *pbr,
+                                    int persist_flag)
+{
+    FILE *stream = NULL;
+    char cmd[64];
+    char *buff = NULL;
+    int ret = 0;
+    int check_value;
+    char *path_prefix = IFACE_CONFIG_FILE_PREFIX_RH;
+    char *path;
+
+    SAFE_MALLOC(buff, CONT_BUFF_SIZE);
+    if ((piface->name == NULL) || (pbr->name == NULL)) {
+        ret = ERR_COMMAND_PARAMETER_WRONG;
+        CU_DEBUG("name was not set, direct goto out.");
+        goto out;
+    }
+
+    check_value = host_br_have_iface_attached_cmd(pbr, piface, NULL);
+    if (check_value < 0) {
+        CU_DEBUG("iface %s or bridge %s do not exist, direct goto out.",
+                        piface->name, pbr->name);
+        ret = ERR_DEVICE_NOT_EXIST;
+        goto out;
+    } else if (check_value == 0) {
+        CU_DEBUG("iface %s is not attached to bridge %s, can't remove it.",
+                        piface->name, pbr->name);
+        ret = ERR_DEVICE_ALREADY_DONE;
+        goto out;
+    } else if (check_value == 2) {
+        CU_DEBUG("iface %s is attached to another device, can't remove it.",
+                        piface->name);
+        ret = ERR_DEVICE_CONNECT_OTHER;
+        goto out;
+    }
+
+    /* building up command line */
+    cmd[sizeof(cmd)-1] = 1;
+    snprintf(cmd, sizeof(cmd), "brctl delif %s %s",
+                        pbr->name, piface->name);
+    if (cmd[sizeof(cmd)-1] == '\0') {
+            CU_DEBUG("cmd line too long, it is [%s].", cmd);
+            ret = ERR_COMMAND_NO_READY;
+            goto out;
+    }
+
+    stream = pipe_excute_command_type_write(cmd, sizeof(cmd), "r", &ret);
+    if (stream == NULL) {
+        goto out;
+    }
+
+    while (fgets(buff, CONT_BUFF_SIZE, stream) != NULL) {
+        CU_DEBUG("get exception: %s", buff);
+        ret = ERR_COMMAND_EXECUTION;
+        goto out;
+    }
+
+    if (persist_flag == 1) {
+        /* if the configuration file do not exist, would not create it */
+        if (LINUX_REDHAT != get_host_linux_version()) {
+            ret = ERR_PERSIST_NOT_REDHAT;
+            CU_DEBUG("Host is not a RedHat version, return is %d",
+                        get_host_linux_version());
+            goto out;
+        }
+        path = combine_file_name(path_prefix, piface->name);
+        ret = configure_file_replace_attr(path, "BRIDGE=", NULL);
+        SAFE_FREE(path);
+        if (ret != 1) {
+            CU_DEBUG("error happened in persisting file.");
+            goto out;
+        }
+    }
+    ret = 1;
+
+out:
+    if (stream != NULL) {
+        pclose(stream);
+        stream = NULL;
+    }
+    SAFE_FREE(buff);
+
+    return ret;
+}
+
+static void merge_eth_list(EthIfacesList *pdest, EthIfacesList *psrc, int flag)
+{
+    int i, j;
+    i = 0;
+    while (i < pdest->count) {
+        j = 0;
+        while (j < psrc->count) {
+            if (1 == eth_iface_compare(pdest->pifaces[i], psrc->pifaces[j])) {
+                /* found the matched device, merge them */
+                eth_iface_merge(pdest->pifaces[i], psrc->pifaces[j], flag);
+                break;
+            }
+            j++;
+        }
+        i++;
+    }
+    return;
+}
+
+static void find_iface_attached_bridge(EthIfacesList *peth_list, EthIface *pbr)
+{
+    int i, j;
+    char *name_on_br, *name_iface;
+    if (pbr->pbr_prop == NULL) {
+        return;
+    }
+    i = 0;
+    while (i < pbr->pbr_prop->port_num) {
+        name_on_br = pbr->pbr_prop->port_names[i];
+        j = 0;
+        while (j < peth_list->count) {
+            name_iface = peth_list->pifaces[j]->name;
+            if (0 == strcmp(name_on_br, name_iface)) {
+                if (peth_list->pifaces[j]->attach_bridge == NULL) {
+                    peth_list->pifaces[j]->attach_bridge =
+                         SAFE_STRDUP(pbr->name);
+                }
+                break;
+            }
+            j++;
+        }
+        i++;
+    }
+}
+
+/* assuming that one peth would be attached to at most 1 bridge */
+static void merge_eth_list_for_bridge(EthIfacesList *peth_list,
+                                      EthIfacesList *pbr_list,
+                                      int flag)
+{
+    int i, j;
+    i = 0;
+    while (i < pbr_list->count) {
+        find_iface_attached_bridge(peth_list, pbr_list->pifaces[i]);
+        j = 0;
+        while (j < peth_list->count) {
+            if (1 == eth_iface_compare(peth_list->pifaces[j],
+                                       pbr_list->pifaces[i])) {
+                /* found the matched device, merge them */
+                eth_iface_merge(peth_list->pifaces[j],
+                                pbr_list->pifaces[i], flag);
+                break;
+            }
+            j++;
+        }
+        i++;
+    }
+    return;
+}
+
+int get_host_eth_ifaces_cmd_all(EthIfacesList *plist,
+                    eth_iface_filter_func filter_func, void *filter_opaque)
+{
+    int retvalue;
+    EthIfacesList *ifaces1, *ifaces2;
+    int i;
+    int filter_ret;
+    int count = 0;
+    SAFE_MALLOC(ifaces1, sizeof(EthIfacesList));
+    SAFE_MALLOC(ifaces2, sizeof(EthIfacesList));
+    eth_ifaceslist_init(ifaces1);
+    eth_ifaceslist_init(ifaces2);
+
+    retvalue = get_host_eth_ifaces_ip_addr(ifaces1->pifaces, &(ifaces1->count),
+                            MAX_IFACE_NUM, NULL, NULL);
+    if (retvalue != 1) {
+        goto out;
+    }
+
+
+    retvalue = get_host_eth_ifaces_ifconfig(ifaces2->pifaces, &(ifaces2->count),
+                            MAX_IFACE_NUM, NULL, NULL);
+    if (retvalue != 1) {
+        goto out;
+    }
+    /* merge the information */
+    merge_eth_list(ifaces1, ifaces2, 1);
+    eth_ifaceslist_uninit(ifaces2);
+
+    retvalue = get_host_eth_ifaces_brctl(ifaces2->pifaces, &(ifaces2->count),
+                            MAX_IFACE_NUM, NULL, NULL);
+    if (retvalue != 1) {
+        goto out;
+    }
+    /* merge the information */
+    merge_eth_list_for_bridge(ifaces1, ifaces2, 1);
+    eth_ifaceslist_uninit(ifaces2);
+
+    retvalue = get_host_eth_ifaces_cat_vlan_config(ifaces2->pifaces,
+                    &(ifaces2->count), MAX_IFACE_NUM, NULL, NULL);
+    if (retvalue != 1) {
+        goto out;
+    }
+
+    /* merge the information */
+    merge_eth_list(ifaces1, ifaces2, 1);
+    eth_ifaceslist_uninit(ifaces2);
+
+    /* filter the result */
+    i = 0;
+    while (i < ifaces1->count) {
+        /* see if the result need to be put to the list */
+        filter_ret = 1;
+        if (filter_func != NULL) {
+            filter_ret = filter_func(ifaces1->pifaces[i], filter_opaque);
+        }
+        if (filter_ret == 1) {
+            if (count >= MAX_IFACE_NUM) {
+                retvalue = ERR_DEVICE_EXCEED_MAXNUM;
+                goto out;
+            }
+            host_iface_adjust(ifaces1->pifaces[i]);
+            plist->pifaces[count] = ifaces1->pifaces[i];
+            ifaces1->pifaces[i] = NULL;
+            count++;
+        }
+        i++;
+    }
+
+ out:
+    eth_ifaceslist_uninit(ifaces1);
+    SAFE_FREE(ifaces1);
+    eth_ifaceslist_uninit(ifaces2);
+    SAFE_FREE(ifaces2);
+    plist->count = count;
+    return retvalue;
+}
diff --git a/libxkutil/host_network_implement_cmdline.h b/libxkutil/host_network_implement_cmdline.h
new file mode 100644
index 0000000..90e5891
--- /dev/null
+++ b/libxkutil/host_network_implement_cmdline.h
@@ -0,0 +1,55 @@
+/*
+ * 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 HOST_NETWORK_IMPLEMENT_CMDLINE_H
+#define HOST_NETWORK_IMPLEMENT_CMDLINE_H
+
+#include "host_network_basic.h"
+
+int get_host_eth_ifaces_ip_addr(EthIface **ppifaces, int *retnum, int maxnum,
+                eth_iface_filter_func filter_func, void *filter_opaque);
+
+int get_host_eth_ifaces_ifconfig(EthIface **ppifaces, int *retnum, int maxnum,
+                eth_iface_filter_func filter_func, void *filter_opaque);
+
+int get_host_eth_ifaces_brctl(EthIface **ppifaces, int *retnum, int maxnum,
+                eth_iface_filter_func filter_func, void *filter_opaque);
+
+int get_host_eth_ifaces_cat_vlan_config(EthIface **ppifaces, int *retnum,
+        int maxnum, eth_iface_filter_func filter_func, void *filter_opaque);
+
+int get_host_eth_ifaces_cmd_all(EthIfacesList *plist,
+                    eth_iface_filter_func filter_func, void *filter_opaque);
+
+int add_host_br_cmd(EthIface *piface, int persist_flag);
+int del_host_br_cmd(EthIface *piface, int persist_flag);
+int mod_host_br_cmd(EthIface *piface, int persist_flag);
+int add_host_iface_to_br_cmd(EthIface *piface, EthIface *pbr,
+                                    int persist_flag);
+int remove_host_iface_from_br_cmd(EthIface *piface, EthIface *pbr,
+                                    int persist_flag);
+
+int add_host_vlan_8021q_cmd(EthIface *piface, int persist_flag);
+int del_host_vlan_8021q_cmd(EthIface *piface, int persist_flag);
+int mod_host_vlan_8021q_cmd(EthIface *piface, int persist_flag);
+
+int change_state_host_iface_cmd(EthIface *piface, int state);
+
+int host_br_have_iface_attached_cmd(EthIface *pbr, EthIface *piface,
+                    EthIface **ppbr_result);
+
+/* check a batch of iface's state with one call of get_host_ifaces,
+   retvalues must be allocated big enough */
+int host_ifacelist_is_present_cmd(EthIfacesList *plist, int *retvalues,
+                                  int compare_name_only);
+
+#endif
-- 
1.7.6





More information about the Libvirt-cim mailing list