function try {
- $1 &>/dev/null || true
+ $1 &>/dev/null || true
}
}
+function delete_neighbor_proxy {
+
+ get_uplink $LINK "-6"
+ get_eui64 $MAC $SUBNET6
+ $SNF_NETWORK_LOG $0 "ip -6 neigh del proxy $EUI64 dev $UPLINK"
+ ip -6 neigh del proxy $EUI64 dev $UPLINK
+
+}
function clear_routed_setup_firewall {
function clear_ebtables {
runlocked $RUNLOCKED_OPTS ebtables -D FORWARD -i $INTERFACE -j $FROM
+ runlocked $RUNLOCKED_OPTS ebtables -D INPUT -i $INTERFACE -j $FROM
runlocked $RUNLOCKED_OPTS ebtables -D FORWARD -o $INTERFACE -j $TO
- #runlocked $RUNLOCKED_OPTS ebtables -D OUTPUT -o $INTERFACE -j $TO
+ runlocked $RUNLOCKED_OPTS ebtables -D OUTPUT -o $INTERFACE -j $TO
runlocked $RUNLOCKED_OPTS ebtables -X $FROM
runlocked $RUNLOCKED_OPTS ebtables -X $TO
function routed_setup_ipv4 {
+ if [ -z "$INTERFACE" -o -z "$NETWORK_GATEWAY" -o -z "$IP" -o -z "$TABLE" ]
+ then
+ return
+ fi
+
# mangle ARPs to come from the gw's IP
arptables -A OUTPUT -o $INTERFACE --opcode request -j mangle --mangle-ip-s "$NETWORK_GATEWAY"
# Enable proxy ARP
echo 1 > /proc/sys/net/ipv4/conf/$INTERFACE/proxy_arp
+
+}
+
+function send_garp {
+
+ # Send GARP from host to upstream router
+ get_uplink $TABLE
+ echo 1 > /proc/sys/net/ipv4/ip_nonlocal_bind
+ $SNF_NETWORK_LOG $0 "arpsend -U -i $IP -c1 $UPLINK"
+ arpsend -U -i $IP -c1 $UPLINK
+ echo 0 > /proc/sys/net/ipv4/ip_nonlocal_bind
+
}
function routed_setup_ipv6 {
# Add a routing entry for the eui-64
- prefix=$NETWORK_SUBNET6
- uplink=$(ip -6 route list table $TABLE | grep "default via" | awk '{print $5}')
- eui64=$($MAC2EUI64 $MAC $prefix)
+ get_uplink $TABLE "-6"
+ get_eui64 $MAC $NETWORK_SUBNET6
+ if [ -z "$EUI64" -o -z "$TABLE" -o -z "$INTERFACE" -o -z "$UPLINK" ]
+ then
+ return
+ fi
ip -6 rule add dev $INTERFACE table $TABLE
- ip -6 ro replace $eui64/128 dev $INTERFACE table $TABLE
- ip -6 neigh add proxy $eui64 dev $uplink
+ ip -6 ro replace $EUI64/128 dev $INTERFACE table $TABLE
+ ip -6 neigh add proxy $EUI64 dev $UPLINK
# disable proxy NDP since we're handling this on userspace
# this should be the default, but better safe than sorry
echo 0 > /proc/sys/net/ipv6/conf/$INTERFACE/proxy_ndp
+
+ # Send Unsolicited Neighbor Advertisement
+ $SNF_NETWORK_LOG $0 "ndsend $EUI64 $UPLINK"
+ ndsend $EUI64 $UPLINK
+
}
# pick a firewall profile per NIC, based on tags (and apply it)
function init_ebtables {
- runlocked $RUNLOCKED_OPTS ebtables -N $FROM
+ runlocked $RUNLOCKED_OPTS ebtables -N $FROM -P RETURN
runlocked $RUNLOCKED_OPTS ebtables -A FORWARD -i $INTERFACE -j $FROM
- runlocked $RUNLOCKED_OPTS ebtables -N $TO
+ # This is needed for multicast packets
+ runlocked $RUNLOCKED_OPTS ebtables -A INPUT -i $INTERFACE -j $FROM
+
+ runlocked $RUNLOCKED_OPTS ebtables -N $TO -P RETURN
runlocked $RUNLOCKED_OPTS ebtables -A FORWARD -o $INTERFACE -j $TO
+ # This is needed for multicast packets
+ runlocked $RUNLOCKED_OPTS ebtables -A OUTPUT -o $INTERFACE -j $TO
}
function setup_ebtables {
# do not allow changes in ip-mac pair
- if [ -n "$IP"]; then
- runlocked $RUNLOCKED_OPTS ebtables -A $FROM --ip-source \! $IP -p ipv4 -j DROP
+ if [ -n "$IP" ]; then
+ :; # runlocked $RUNLOCKED_OPTS ebtables -A $FROM --ip-source \! $IP -p ipv4 -j DROP
fi
runlocked $RUNLOCKED_OPTS ebtables -A $FROM -s \! $MAC -j DROP
- #accept dhcp responses from host (nfdhcpd)
- runlocked $RUNLOCKED_OPTS ebtables -A $TO -p ipv4 --ip-protocol=udp --ip-destination-port=68 -j ACCEPT
+ # accept dhcp responses from host (nfdhcpd)
+ # this is actually not needed because nfdhcpd opens a socket and binds is with
+ # tap interface so dhcp response does not go through bridge
+ # runlocked $RUNLOCKED_OPTS ebtables -A $TO -s $INDEV_MAC -p ipv4 --ip-protocol=udp --ip-destination-port=68 -j ACCEPT
# allow only packets from the same mac prefix
runlocked $RUNLOCKED_OPTS ebtables -A $TO -s \! $MAC/$MAC_MASK -j DROP
}
}
+function get_uplink {
+
+ local table=$1
+ local version=$2
+ UPLINK=$(ip "$version" route list table "$table" | grep "default via" | awk '{print $5}')
+
+}
+
+# Because we do not have IPv6 value in our environment
+# we caclulate it based on the NIC's MAC and the IPv6 subnet (if any)
+# first argument MAC second IPv6 subnet
+# Changes global value EUI64
+get_eui64 () {
+
+ local mac=$1
+ local prefix=$2
+
+ if [ -z "$prefix" ]; then
+ EUI64=
+ else
+ EUI64=$($MAC2EUI64 $mac $prefix)
+ fi
+
+}
+
+
+# DDNS related functions
+
+# ommit zone statement
+# nsupdate will attempt determine the correct zone to update based on the rest of the input
+send_command () {
+
+ local command="$1"
+ $SNF_NETWORK_LOG $0 "$command"
+ nsupdate -k $KEYFILE > /dev/null << EOF
+ server $SERVER
+ $command
+ send
+EOF
+
+}
+
+
+update_arecord () {
+
+ local action=$1
+ local command=
+ if [ -n "$IP" ]; then
+ command="update $action $GANETI_INSTANCE_NAME.$FZONE $TTL A $IP"
+ send_command "$command"
+ fi
+
+}
+
+
+update_aaaarecord () {
+
+ local action=$1
+ local command=
+ if [ -n "$EUI64" ]; then
+ command="update $action $GANETI_INSTANCE_NAME.$FZONE $TTL AAAA $EUI64"
+ send_command "$command"
+ fi
+
+}
+
+
+update_ptrrecord () {
+
+ local action=$1
+ local command=
+ if [ -n "$IP" ]; then
+ command="update $action $RLPART.$RZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
+ send_command "$command"
+ fi
+
+}
+
+update_ptr6record () {
+
+ local action=$1
+ local command=
+ if [ -n "$EUI64" ]; then
+ command="update $action $R6LPART$R6ZONE. $TTL PTR $GANETI_INSTANCE_NAME.$FZONE"
+ send_command "$command"
+ fi
+
+}
+
+update_all () {
+
+ local action=$1
+ update_arecord $action
+ update_aaaarecord $action
+ update_ptrrecord $action
+ update_ptr6record $action
+
+}
+
+
+# first argument is an eui64 (IPv6)
+# sets GLOBAL args R6REC, R6ZONE, R6LPART
+# lets assume eui64=2001:648:2ffc:1::1
+# the following commands produce:
+# R6REC=1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.1.0.0.0.c.f.f.2.8.4.6.0.1.0.0.2.ip6.arpa
+# R6ZONE=1.0.0.0.c.f.f.2.8.4.6.0.1.0.0.2.ip6.arpa
+# R6LPART=1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.
+get_rev6_info () {
+
+ local eui64=$1
+ if [ -z "$eui64" ]; then
+ R6REC= ; R6ZONE= ; R6LPART= ;
+ else
+ R6REC=$(host $eui64 | egrep -o '([[:alnum:]]\.){32}ip6.arpa' )
+ R6ZONE=$(echo $R6REC | awk -F. 'BEGIN{rpart="";} { for (i=32;i>16;i=i-1) rpart=$i "." rpart; } END{print rpart "ip6.arpa";}')
+ R6LPART=$(echo $R6REC | awk -F. 'BEGIN{lpart="";} { for (i=16;i>0;i=i-1) lpart=$i "." lpart; } END{print lpart;}')
+ fi
+
+}
+
+
+# first argument is an ipv4
+# sets args RZONE, RLPART
+# lets assume IP=203.0.113.1
+# RZONE="113.0.203.in-add.arpa"
+# RLPART="1"
+get_rev4_info () {
+
+ local ip=$1
+ if [ -z "$ip" ]; then
+ RZONE= ; RLPART= ;
+ else
+ OLDIFS=$IFS
+ IFS=". "
+ set -- $ip
+ a=$1 ; b=$2; c=$3; d=$4;
+ IFS=$OLDIFS
+ RZONE="$c.$b.$a.in-addr.arpa"
+ RLPART="$d"
+ fi
+
+}
+
+
+# Query nameserver for entries related to the specific instance
+# An example output is the following:
+# www.google.com has address 173.194.113.114
+# www.google.com has address 173.194.113.115
+# www.google.com has address 173.194.113.116
+# www.google.com has address 173.194.113.112
+# www.google.com has address 173.194.113.113
+# www.google.com has IPv6 address 2a00:1450:4001:80b::1012
+query_dns () {
+
+ HOSTQ="host -s -R 3 -W 3"
+ HOST_IP_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has address //p')
+ HOST_IP6_ALL=$($HOSTQ $GANETI_INSTANCE_NAME.$FZONE $SERVER | sed -n 's/.*has IPv6 address //p')
+
+}