#!/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