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