Implement colo nic device interface configure() add a script to configure nic devices: ${QEMU_SCRIPT_DIR}/colo-proxy-script.sh
Cc: Stefan Hajnoczi <stefa...@redhat.com> Cc: Jason Wang <jasow...@redhat.com> Signed-off-by: zhanghailiang <zhang.zhanghaili...@huawei.com> Signed-off-by: Li Zhijian <lizhij...@cn.fujitsu.com> --- include/net/tap.h | 17 ++++++++ net/colo-nic.c | 48 ++++++++++++++++++++++- net/tap.c | 17 -------- scripts/colo-proxy-script.sh | 92 ++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 156 insertions(+), 18 deletions(-) create mode 100755 scripts/colo-proxy-script.sh diff --git a/include/net/tap.h b/include/net/tap.h index ac99b31..9688765 100644 --- a/include/net/tap.h +++ b/include/net/tap.h @@ -29,6 +29,23 @@ #include "qemu-common.h" #include "qapi-types.h" #include "standard-headers/linux/virtio_net.h" +#include "net/net.h" +#include "net/vhost_net.h" + +typedef struct TAPState { + NetClientState nc; + int fd; + char down_script[1024]; + char down_script_arg[128]; + uint8_t buf[NET_BUFSIZE]; + bool read_poll; + bool write_poll; + bool using_vnet_hdr; + bool has_ufo; + bool enabled; + VHostNetState *vhost_net; + unsigned host_vnet_hdr_len; +} TAPState; int tap_enable(NetClientState *nc); int tap_disable(NetClientState *nc); diff --git a/net/colo-nic.c b/net/colo-nic.c index b6a8330..4ce08c0 100644 --- a/net/colo-nic.c +++ b/net/colo-nic.c @@ -15,6 +15,7 @@ #include "net/net.h" #include "net/colo-nic.h" #include "qemu/error-report.h" +#include "net/tap.h" typedef struct nic_device { COLONicState *cns; @@ -23,8 +24,53 @@ typedef struct nic_device { bool is_up; } nic_device; +static int launch_colo_script(COLONicState *cns, bool up, int side, int index) +{ + NetClientState *nc = container_of(cns, NetClientState, cns); + TAPState *s = DO_UPCAST(TAPState, nc, nc); + int i, argc = 6; + char *argv[7], index_str[32]; + char **parg; + Error *err = NULL; + + parg = argv; + *parg++ = cns->script; + *parg++ = (char *)(side == COLO_MODE_SECONDARY ? "secondary" : "primary"); + *parg++ = (char *)(up ? "install" : "uninstall"); + *parg++ = cns->nicname; + *parg++ = cns->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; + } + } + + launch_script(argv, s->fd, &err); + if (err) { + error_report_err(err); + return -1; + } + return 0; +} + QTAILQ_HEAD(, nic_device) nic_devices = QTAILQ_HEAD_INITIALIZER(nic_devices); +static int colo_nic_configure(COLONicState *cns, + bool up, int side, int index) +{ + if (!cns && index <= 0) { + error_report("Can not parse colo_script or forward_nic"); + return -1; + } + + return launch_colo_script(cns, up, side, index); +} + void colo_add_nic_devices(COLONicState *cns) { struct nic_device *nic; @@ -43,7 +89,7 @@ void colo_add_nic_devices(COLONicState *cns) } nic = g_malloc0(sizeof(*nic)); - nic->configure = NULL; + nic->configure = colo_nic_configure; nic->cns = cns; QTAILQ_INSERT_TAIL(&nic_devices, nic, next); diff --git a/net/tap.c b/net/tap.c index a715636..0e3bdbd 100644 --- a/net/tap.c +++ b/net/tap.c @@ -43,23 +43,6 @@ #include "net/tap.h" #include "net/colo-nic.h" -#include "net/vhost_net.h" - -typedef struct TAPState { - NetClientState nc; - int fd; - char down_script[1024]; - char down_script_arg[128]; - uint8_t buf[NET_BUFSIZE]; - bool read_poll; - bool write_poll; - bool using_vnet_hdr; - bool has_ufo; - bool enabled; - VHostNetState *vhost_net; - unsigned host_vnet_hdr_len; -} TAPState; - static void tap_send(void *opaque); static void tap_writable(void *opaque); diff --git a/scripts/colo-proxy-script.sh b/scripts/colo-proxy-script.sh new file mode 100755 index 0000000..47c4fb5 --- /dev/null +++ b/scripts/colo-proxy-script.sh @@ -0,0 +1,92 @@ +#!/bin/sh +#usage: +# colo-proxy-script.sh primary/secondary install/uninstall phy_if virt_if index +#.e.g: +# colo-proxy-script.sh primary 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 primary/secondary " + echo -e "install/uninstall phy_if virt_if index\n" +} + +primary_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 +} + +primary_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 -D INPUT -i $phy_if -j MARK --set-mark $index +} + +secondary_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 +} + +secondary_uninstall() +{ + brctl delif $br $phy_if + brctl delif $br $virt_if + brctl addif $failover_br $virt_if + + /usr/local/sbin/iptables -t mangle -D PREROUTING -m physdev --physdev-in \ + $virt_if -j SECCOLO --index $index + /usr/local/sbin/ip6tables -t mangle -D PREROUTING -m physdev --physdev-in \ + $virt_if -j SECCOLO --index $index +} + +if [ $# -ne 5 ]; then + script_usage + exit 1 +fi + +if [ "x$side" != "xprimary" ] && [ "x$side" != "xsecondary" ]; then + script_usage + exit 2 +fi + +if [ "x$action" != "xinstall" ] && [ "x$action" != "xuninstall" ]; then + script_usage + exit 3 +fi + +${side}_${action} -- 1.8.3.1