Bash Script Not Working Bandwidth Shaping
<p>I hope this is an easy answer</p>

<p>Problems:</p>

<ol>
<li>I placed the following bash script called learn-address.sh in the following folder:</li>
</ol>

<blockquote>
  <p><code>vi /etc/openvpn/netem/learn-address.sh</code></p>
</blockquote>

<ol start="2">
<li>Added the following (2) lines to the .conf file:</li>
</ol>

<blockquote>
<pre><code>script-security 3

learn-address /etc/openvpn/netem/learn-address.sh
</code></pre>
</blockquote>

<ol start="3">
<li>And applied the following permission to the learn-address script:</li>
</ol>

<blockquote>
<pre><code>chmod 755 /etc/openvpn/netem/learn-address.sh
</code></pre>
</blockquote>

<ol>
<li><p>However, the script does update the files ($ip.classid and $ip.dev)
in the tmp file and passes the variables correctly</p></li>
<li><p>But the bash script does not execute the tc class and filter commands (there is no change to qdisc)</p></li>
<li><p>What permissions would I use on the script to execute the tc class and filter commands when the learn-address script is called when a user connects to OpenVPN or is there something else that I missed?</p></li>
</ol>

<p>Many thanks</p>

<p>Name of script: learn-address.sh</p>

<pre><code>#!/bin/bash

statedir=/tmp/

function bwlimit-enable() {
ip=$1
user=$2
dev=eth0

# Disable if already enabled.
bwlimit-disable $ip

# Find unique classid.
if [ -f $statedir/$ip.classid ]; then
    # Reuse this IP's classid
    classid=`cat $statedir/$ip.classid`
else
    if [ -f $statedir/last_classid ]; then
        classid=`cat $statedir/last_classid`
        classid=$((classid+1))
    else
        classid=1
    fi
    echo $classid &gt; $statedir/last_classid
fi

# Find this user's bandwidth limit
# downrate: from VPN server to the client
# uprate: from client to the VPN server
if [ "$user" == "myuser" ]; then
    downrate=10mbit
    uprate=10mbit
elif [ "$user" == "anotheruser"]; then
    downrate=2mbit
    uprate=2mbit
else
    downrate=5mbit
    uprate=5mbit
fi

# Limit traffic from VPN server to client
tc class add dev $dev parent 1: classid 1:$classid htb rate $downrate
tc filter add dev $dev protocol all parent 1:0 prio 1 u32 match ip dst $ip/32 flowid 1:$classid

# Limit traffic from client to VPN server
tc filter add dev $dev parent ffff: protocol all prio 1 u32 match ip src $ip/32 police rate $uprate burst 80k drop flowid :$classid

# Store classid and dev for further use.
echo $classid &gt; $statedir/$ip.classid
echo $dev &gt; $statedir/$ip.dev
}

function bwlimit-disable() {
ip=$1

if [ ! -f $statedir/$ip.classid ]; then
    return
fi
if [ ! -f $statedir/$ip.dev ]; then
    return
fi

classid=`cat $statedir/$ip.classid`
dev=`cat $statedir/$ip.dev`

tc filter del dev $dev protocol all parent 1:0 prio 1 u32 match ip dst $ip/32
tc class del dev $dev classid 1:$classid

tc filter del dev $dev parent ffff: protocol all prio 1 u32 match ip src $ip/32

# Remove .dev but keep .classid so it can be reused.
rm $statedir/$ip.dev
}

# Make sure queueing discipline is enabled.
tc qdisc add dev $dev root handle 1: htb 2&gt;/dev/null || /bin/true
tc qdisc add dev $dev handle ffff: ingress 2&gt;/dev/null || /bin/true

case "$1" in
    add|update)
        bwlimit-enable $2 $3
        ;;
    delete)
        bwlimit-disable $2
        ;;
    *)
        echo "$0: unknown operation [$1]" &gt;&amp;2
        exit 1
        ;;
esac

exit 0
</code></pre>