#!/bin/bash set -ex lock_file=/var/lock/openshift-sdn.lock action=$1 veth_host=$2 macaddr=$3 ipaddr=$4 tenant_id=$5 ingress_bw=$6 egress_bw=$7 lockwrap() { ( flock 200 "$@" ) 200>${lock_file} } add_ovs_port() { ovs-vsctl add-port br0 ${veth_host} } ensure_ovs_port() { ovs-vsctl --may-exist add-port br0 ${veth_host} } del_ovs_port() { ovs-vsctl --if-exists del-port $veth_host } add_ovs_flows() { ovs_port=$(ovs-vsctl get Interface ${veth_host} ofport) if [ -z "$ovs_port" ]; then echo "Could not find OVS port for veth device ${veth_host} of container ${net_container}" exit 1 fi # from container ovs-ofctl -O OpenFlow13 add-flow br0 "table=20, priority=100, in_port=${ovs_port}, arp, nw_src=${ipaddr}, arp_sha=${macaddr}, actions=load:${tenant_id}->NXM_NX_REG0[], goto_table:30" ovs-ofctl -O OpenFlow13 add-flow br0 "table=20, priority=100, in_port=${ovs_port}, ip, nw_src=${ipaddr}, actions=load:${tenant_id}->NXM_NX_REG0[], goto_table:30" # arp request/response to container (not isolated) ovs-ofctl -O OpenFlow13 add-flow br0 "table=40, priority=100, arp, nw_dst=${ipaddr}, actions=output:${ovs_port}" # IP to container ovs-ofctl -O OpenFlow13 add-flow br0 "table=70, priority=100, ip, nw_dst=${ipaddr}, actions=load:${tenant_id}->NXM_NX_REG1[], load:${ovs_port}->NXM_NX_REG2[], goto_table:80" # Pod ingress == OVS bridge egress # linux-htb used here since that's the Kubernetes default traffic shaper too if [ -n "${ingress_bw}" ]; then ip link set dev ${veth_host} qlen 1000 qos=$(ovs-vsctl create qos type=linux-htb other-config:max-rate=${ingress_bw}) ovs-vsctl set port ${veth_host} qos=${qos} fi # Pod egress == OVS bridge ingress if [ -n "${egress_bw}" ]; then # OVS ingress_policing specified in Kbps ovs-vsctl set interface ${veth_host} ingress_policing_rate=$((${egress_bw}/1000)) fi } del_ovs_flows() { ovs-ofctl -O OpenFlow13 del-flows br0 "ip,nw_dst=${ipaddr}" ovs-ofctl -O OpenFlow13 del-flows br0 "ip,nw_src=${ipaddr}" ovs-ofctl -O OpenFlow13 del-flows br0 "arp,nw_dst=${ipaddr}" ovs-ofctl -O OpenFlow13 del-flows br0 "arp,nw_src=${ipaddr}" qos=$(ovs-vsctl get port ${veth_host} qos || true) if [ -n "${qos}" -a "${qos}" != "[]" ]; then ovs-vsctl clear port ${veth_host} qos ovs-vsctl --if-exists destroy qos ${qos} fi } run() { case "$action" in setup) add_ovs_port add_ovs_flows ;; update) ensure_ovs_port del_ovs_flows add_ovs_flows ;; teardown) del_ovs_flows # Delete ovs port in the end, del_ovs_flows needs the port to delete qos record del_ovs_port ;; *) echo "Bad input: $@" exit 1 esac } lockwrap run