-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpdsplit.sh.template
More file actions
123 lines (109 loc) · 4.58 KB
/
pdsplit.sh.template
File metadata and controls
123 lines (109 loc) · 4.58 KB
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
#!/bin/sh
# File: __HLPPATH__/pdsplit.sh
# Generated by __INSTALLERPATH__ on: __DATE__
#
# Description: Helper for dibbler-client to split a delegated /64 or shorter.
# Binds the first address in the first /64 subnet within the PD to a LAN
# interface. May bind the second address in the first /64 to a WAN interface.
# Also tries to set a default IPv6 route.
#
# This script should be called by dibbler-client after it has received an
# address and a prefix delegation. It relies on environment variables
# available when it is called this way and will not work otherwise.
#
# IPv6 connectivity for LAN clients requires, at a minimum, sending Router
# Advertisements (with radvd/dnsmasq) to the LAN interface and enabling IPv6
# forwarding in the kernel. An ip6tables firewall is also a very good idea.
#
# Recommended: rdisc6 (ICMPv6 Router Discovery tool, Debian package name ndisc6)
# LAN interface to which the PD should be bound
LAN=__LAN__
# Bind $PREFIX1::1 to WAN interface?
BINDWAN=__BINDWAN__
script=$(basename $0)
logpath="__LOGPATH__"; mkdir -p "$logpath"
logfile="$logpath/$(basename $script .sh).log"
reason=manual; [ -n "$1" ] && reason=$1
# DEBUG: Uncomment the 3 lines below, restart dibbler-client, & check the .dbg
# file for cmdline, cmdline args, & environment variables at script runtime.
# dbg="/tmp/pdsplit.dbg"
# echo $(for arg in "$0" "$@"; do echo -n "'$arg' "; done; echo; echo) > $dbg
# env 2>&1 >> $dbg
log() {
msg="$1";
[ "$2" = "1" ] && msg="$msg unnecessary, moving on"
[ "$2" = "2" ] && msg="$msg succeeded"
echo -n "$(date '+%Y.%m.%d %T') $script $msg" >> "$logfile"
echo >> "$logfile"
}
die() { log "EXIT WITH ERROR: $*"; exit 1; }
log "started, reason: $reason"
[ -x "$(which ip)" ] || die "ip utility from iproute2 not found"
[ "$reason" = "manual" ] && die "should only be called by dibbler-client"
[ $PREFIX1LEN -le 64 ] && GUA64="$PREFIX1/64" && GUA128="${PREFIX1}1/128" ||
die "received prefix longer than a /64"
# If 2600:1700:xxx0:xxx0::/64 is not bound to LAN, purge all other global
# unicast addresses and add it.
replace_lan_gua() {
msg="binding $GUA64 to LAN interface $LAN"
if ip -6 -br addr show dev $LAN | grep -q $LAN $GUA64; then
log "$msg" 1
else
ip -6 addr flush dev $LAN scope global &&
ip -6 addr add $GUA64 dev $LAN && log "$msg" 2 || die "$msg"
fi
}
# If 2600:1700:xxx0:xxx0::1/128 is not bound to WAN, add it.
add_wan_gua() {
msg="binding $GUA128 to WAN interface $IFACE"
if ip -6 -br addr show dev $IFACE | grep -q $GUA128; then
log "$msg" 1
else
ip -6 addr add $GUA128 dev $IFACE && log "$msg" 2 || die "$msg"
fi
}
fixup_default_route() {
old_gateway=$(ip -6 route show default | awk '{print $3}')
new_gateway=$(rdisc6 -n $IFACE | tail -1 | awk '{print $2}')
# Running rdisc6 should just refresh the default route. If it added a new one
# entirely, purge the new default route & rerun rdisc6 to be extra thorough
msg="purging and readding default route"
if [ "$old_gateway" = "$new_gateway" ]; then
log "$msg" 1
else
ip -6 route flush default &&
rdisc6 -n $IFACE 2>&1 1>/dev/null && log "$msg" 2 || die "failed"
fi
log "default IPv6 route is via $new_gateway on dev $IFACE"
}
skip_fixup() {
cur_gateway=$(ip -6 route show default | awk '{print $3}')
log "rdisc6 not installed, will not send Router Solicitation"
log "IPv6 connectivity to WAN may fail or be delayed"
[ -z "$cur_gateway" ] && log "no default IPv6 route yet" ||
log "default IPv6 route is via $cur_gateway"
}
case "$reason" in
add|update)
replace_lan_gua; [ "$BINDWAN" = "yes" ] && add_wan_gua
# Listen for RAs on WAN, even if IPv6 forwarding is enabled
log "accepting Router Advertisements on $IFACE"
echo 2 > /proc/sys/net/ipv6/conf/$IFACE/accept_ra
[ -x "$(which rdisc6)" ] && fixup_default_route || skip_fixup
;;
delete)
msg="removing the default IPv6 route"
ip -6 route flush default && log "$msg" 2 || die "$msg"
msg="removing all global unicast addresses on LAN interface $LAN"
ip -6 addr flush dev $LAN scope global && log "$msg 2" || die "$msg"
msg="removing all global unicast addresses on WAN interface $IFACE"
ip -6 addr flush dev $WAN scope global && log "$msg 2" || die "$msg"
# Alternative: remove only the 2600:1700:xxx0:xxx0::1/128 address on WAN
# GUA128=$(ip -6 -br addr show dev $IFACE 2>/dev/null)
# GUA128=$(echo $GUA128 | grep -o "2600:1700:.*0:.*0::1/128" 2>/dev/null)
# [ -z "$GUA128" ] && return
# msg="removing $GUA128 on WAN interface $IFACE"
# ip -6 addr del $GUA128 dev $IFACE && log "$msg" 2 || die "$msg"
;;
esac
log "finished"