summaryrefslogtreecommitdiffstats
path: root/vserver.functions
blob: a75d717fe61c5aa34b217d698f48ed2fb5bb848d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# source the real file
. ${__REAL_PKGLIBDIR}/vserver.functions
__PKGLIBDIR="${__REAL_PKGLIBDIR}"

#
# own functions
#

function netnsCreateMac() {
    local mac

    getFileValue mac "${1}/mac"
    if [ -n "$mac" ]; then
        echo "$mac"
        return 0
    fi

    getFileValue ctx "$VSERVER_DIR"/context
    (
        printf "0200"
        printf "%06d" $ctx
        printf "%02x" "$(basename "$1")"
    )|
    sed 's/\(..\)\(..\)\(..\)\(..\)\(..\)\(..\)/\1:\2:\3:\4:\5:\6/'
}

function netnsCreateIfaceName() {
    local name

    getFileValue name "${1}/name"
    if [ -n "$name" ]; then
        echo "$name"
        return 0
    fi

    printf "%s%d" "$VSERVER_NAME" "$(basename "$1")"
}

function _netnsProcessSingleGateway() {
    local iface
    local gw

    getFileValue gw "${1}/gw" "${1}/../gw"
    [ -n "$gw" ] || return 0

    iface="$(netnsCreateIfaceName "$1")"
    _addInterfaceCmd IP_ROUTE default via "$gw" dev "$iface"
}

function _netnsFilterNetnsUmount() {
    local args=( "$@" )

    while :
    do
        case $1 in
            --) shift; break;;
            -*) shift;;
            net:*|/run/netns/*) return 0;;
            *) break;;
        esac
    done

    ${_REAL_UMOUNT} "${args[@]}"
}

function _netnsWaitForDad() {
    local waiting

    while ip -6 -o addr show tentative | grep -q ' scope global '; do
        sleep 1
        waiting=$((waiting+1))
        if [ "$waiting" -ge "$1" ]; then
            echo "Warning: IPv6 addresses still tentative after ${waiting} seconds; continuing..."
            return 0
        fi
    done
}


#
# monkey patching
#

function save_function() {
    local ORIG_FUNC=$(declare -f $1)
    local NEWNAME_FUNC="$2${ORIG_FUNC#$1}"
    eval "$NEWNAME_FUNC"
}

save_function _generateInterfaceOptions __netns_realGenerateInterfaceOptions
function _generateInterfaceOptions() {
    __netns_realGenerateInterfaceOptions "$@"
    ret=$?

    # add commands for default route
    for net in "$VSERVER_DIR/netns/"*; do
        test   -d "$net"            || continue
        test ! -e "${net}/disabled" || continue

        _netnsProcessSingleGateway "$net"
    done

    return $ret
}

save_function _namespaceCleanup __netns_realNamespaceCleanup
function _namespaceCleanup() {
    _REAL_UMOUNT="${_UMOUNT}"
    _UMOUNT="_netnsFilterNetnsUmount"

    __netns_realNamespaceCleanup "$@"
    ret=$?

    _UMOUNT="${_REAL_UMOUNT}"
    return $ret
}

save_function enableInterfaces __netns_realEnableInterfaces
function enableInterfaces() {
    __netns_realEnableInterfaces "$@"
    ret=$?

    # It is unpossible to bind on very recently added IPv6 addresses.
    # They have to pass the duplicate address detection (dad) before
    # they could be used, so we wait here before continuing.
    _netnsWaitForDad 10

    return $ret
}