Implement colo nic device interface configure()
add a script to configure nic devices:
${QEMU_SCRIPT_DIR}/colo-proxy-script.sh

Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com>
Signed-off-by: Li Zhijian <lizhij...@cn.fujitsu.com>
---
 net/colo-nic.c               | 56 +++++++++++++++++++++++++++-
 scripts/colo-proxy-script.sh | 88 ++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 143 insertions(+), 1 deletion(-)
 create mode 100755 scripts/colo-proxy-script.sh

diff --git a/net/colo-nic.c b/net/colo-nic.c
index d021526..8b678b1 100644
--- a/net/colo-nic.c
+++ b/net/colo-nic.c
@@ -38,12 +38,66 @@ static bool colo_nic_support(NetClientState *nc)
     return nc && nc->colo_script[0] && nc->colo_nicname[0];
 }
 
+static int launch_colo_script(char *argv[])
+{
+    int pid, status;
+    char *script = argv[0];
+
+    /* try to launch network script */
+    pid = fork();
+    if (pid == 0) {
+        execv(script, argv);
+        _exit(1);
+    } else if (pid > 0) {
+        while (waitpid(pid, &status, 0) != pid) {
+            /* loop */
+        }
+
+        if (WIFEXITED(status) && WEXITSTATUS(status) == 0) {
+            return 0;
+        }
+    }
+    return -1;
+}
+
+static int colo_nic_configure(NetClientState *nc,
+            bool up, int side, int index)
+{
+    int i, argc = 6;
+    char *argv[7], index_str[32];
+    char **parg;
+
+    if (!nc && index <= 0) {
+        error_report("Can not parse colo_script or colo_nicname");
+        return -1;
+    }
+
+    parg = argv;
+    *parg++ = nc->colo_script;
+    *parg++ = (char *)(side == COLO_SECONDARY_MODE ? "slave" : "master");
+    *parg++ = (char *)(up ? "install" : "uninstall");
+    *parg++ = nc->colo_nicname;
+    *parg++ = nc->ifname;
+    sprintf(index_str, "%d", index);
+    *parg++ = index_str;
+    *parg = NULL;
+
+    for (i = 0; i < argc; i++) {
+        if (!argv[i][0]) {
+            error_report("Can not get colo_script argument");
+            return -1;
+        }
+    }
+
+    return launch_colo_script(argv);
+}
+
 void colo_add_nic_devices(NetClientState *nc)
 {
     struct nic_device *nic = g_malloc0(sizeof(*nic));
 
     nic->support_colo = colo_nic_support;
-    nic->configure = NULL;
+    nic->configure = colo_nic_configure;
     /*
      * TODO
      * only support "-netdev tap,colo_scripte..."  options
diff --git a/scripts/colo-proxy-script.sh b/scripts/colo-proxy-script.sh
new file mode 100755
index 0000000..ed0fcb8
--- /dev/null
+++ b/scripts/colo-proxy-script.sh
@@ -0,0 +1,88 @@
+#!/bin/sh
+#usage: colo-proxy-script.sh master/slave install/uninstall phy_if virt_if 
index
+#.e.g colo-proxy-script.sh master install eth2 tap0 1
+
+side=$1
+action=$2
+phy_if=$3
+virt_if=$4
+index=$5
+br=br1
+failover_br=br0
+
+script_usage()
+{
+    echo -n "usage: ./colo-proxy-script.sh master/slave "
+    echo -e "install/uninstall phy_if virt_if index\n"
+}
+
+master_install()
+{
+    tc qdisc add dev $virt_if root handle 1: prio
+    tc filter add dev $virt_if parent 1: protocol ip prio 10 u32 match u32 \
+        0 0 flowid 1:2 action mirred egress mirror dev $phy_if
+    tc filter add dev $virt_if parent 1: protocol arp prio 11 u32 match u32 \
+        0 0 flowid 1:2 action mirred egress mirror dev $phy_if
+    tc filter add dev $virt_if parent 1: protocol ipv6 prio 12 u32 match u32 \
+        0 0 flowid 1:2 action mirred egress mirror dev $phy_if
+
+    /usr/local/sbin/iptables -t mangle -I PREROUTING -m physdev --physdev-in \
+        $virt_if -j PMYCOLO --index $index --forward-dev $phy_if
+    /usr/local/sbin/ip6tables -t mangle -I PREROUTING -m physdev --physdev-in \
+        $virt_if -j PMYCOLO --index $index --forward-dev $phy_if
+    /usr/local/sbin/arptables -I INPUT -i $phy_if -j MARK --set-mark $index
+}
+
+master_uninstall()
+{
+    tc filter del dev $virt_if parent 1: protocol ip prio 10 u32 match u32 \
+        0 0 flowid 1:2 action mirred egress mirror dev $phy_if
+    tc filter del dev $virt_if parent 1: protocol arp prio 11 u32 match u32 \
+        0 0 flowid 1:2 action mirred egress mirror dev $phy_if
+    tc filter del dev $virt_if parent 1: protocol ipv6 prio 12 u32 match u32 \
+        0 0 flowid 1:2 action mirred egress mirror dev $phy_if
+    tc qdisc del dev $virt_if root handle 1: prio
+
+    /usr/local/sbin/iptables -t mangle -D PREROUTING -m physdev --physdev-in \
+        $virt_if -j PMYCOLO --index $index --forward-dev $phy_if
+    /usr/local/sbin/ip6tables -t mangle -D PREROUTING -m physdev --physdev-in \
+        $virt_if -j PMYCOLO --index $index --forward-dev $phy_if
+    /usr/local/sbin/arptables -F
+}
+
+slave_install()
+{
+    brctl addif $br $phy_if
+
+    /usr/local/sbin/iptables -t mangle -I PREROUTING -m physdev --physdev-in \
+        $virt_if -j SECCOLO --index $index
+    /usr/local/sbin/ip6tables -t mangle -I PREROUTING -m physdev --physdev-in \
+        $virt_if -j SECCOLO --index $index
+}
+
+slave_uninstall()
+{
+    brctl delif $br $phy_if
+    brctl delif $br $virt_if
+    brctl addif $failover_br $virt_if
+
+    /usr/local/sbin/iptables -t mangle -F
+    /usr/local/sbin/ip6tables -t mangle -F
+}
+
+if [ $# -ne 5 ]; then
+    script_usage
+    exit 1
+fi
+
+if [ "x$side" != "xmaster" ] && [ "x$side" != "xslave" ]; then
+    script_usage
+    exit 2
+fi
+
+if [ "x$action" != "xinstall" ] && [ "x$action" != "xuninstall" ]; then
+    script_usage
+    exit 3
+fi
+
+${side}_${action}
-- 
1.7.12.4



Reply via email to