summaryrefslogblamecommitdiffstats
path: root/modules.d/slx-network/scripts/udhcpc-trigger.stage3
blob: a9eadea34b83a88f61dac1527de70fde92b4f825 (plain) (tree)
1
2
3
4
5
6
7
8
9



                                                             
 

               
      
                                        

                 




                                                                     
                                             

                                                        


              



                                




                             




                                                                             
                                                      
                                                        
                                                                          
                                                                                                                                               

                                                                   


                                                  
                          

                                                                   
                                                                                                
                                                          
  

                                    

                                                                                 

                                                                                   
          
                                                              
                                                            

  




                                   

                           


                               
                                        
                                                                            
                                             
                                                                                     
          



                                                  

                      
                               
                                                




                                                                                  
  
 
                  


                                                  
                                                                                        

                    
                       
                                                                                
               




                                        
  
 














                                                                              
  
 






                                                                                                                 



                                                          
                                                  




                                                       
 


                                                   
                                                          
  
 

                                                   
                                                          


                         
                                                        

  




                                                                                                           
 








                                                  
 
               
      
                                                         
#!/bin/bash
#
# This script is triggered by udhcpc in stage3 and handle the
# DHCP information given as parameters

{
# for debugging
set -x
NETWORK_CONF="/run/openslx/network.conf"
. "$NETWORK_CONF"

MAIN_NETIF="$SLX_PXE_NETIF"
[ -n "$SLX_VLAN_ID" ] && MAIN_NETIF="${SLX_PXE_NETIF}.${SLX_VLAN_ID}"
[ -n "$SLX_BRIDGE" ]  && MAIN_NETIF="$SLX_BRIDGE"
readonly MAIN_NETIF

if [[ "$1" != "bound" && "$1" != "renew" ]] \
		|| [ "$interface" != "${MAIN_NETIF}" ] \
		|| [ -z "$ip" ]; then
	exit 0
fi

log() {
	echo "${MAIN_NETIF}: $*"
}

##
## CORE NETWORK CONFIGURATION
##
## > IP, subnet, route

# If we already got an IP from KCL, see if it differs, and remove first if so
# We just try to prevent everything from breaking if the DHCP server doesn't
# objey the renew request by the client and hands out a new address
if [ -n "$SLX_PXE_CLIENT_IP" ]; then
	#...some address is already configured...
	if [ "${SLX_PXE_CLIENT_IP}" != "${ip}" ]; then
		#...it's a different one, reconfigure...
		log "reconfiguring from '${SLX_PXE_CLIENT_IP}' to '${ip}'"
		# remove default route and let it be added again below, as it might get lost when changing the primary address on the interface
		ip route del default
		ip addr del "$SLX_PXE_CLIENT_IP" dev "${interface}"
	fi
else
	#...no address configured yet, just add...
	log "adding ${ip}"
fi
if ! ip addr show dev "${interface}" | grep -qF "inet ${ip}/"; then
	ip addr add "${ip}/$(ipcalc -s -p "${ip}" "${subnet}" | sed s/.*=//)" dev "${interface}"
	echo "SLX_DHCP_CLIENT_IP='$ip'" >> "$NETWORK_CONF"
fi

# Same procedure for default gateway
if [ -n "$router" ]; then
	if [ -n "$SLX_PXE_GATEWAY" ] && [ "$SLX_PXE_GATEWAY" != "$router" ]; then
		log "reconfiguring default gw from '$SLX_PXE_GATEWAY' to '$router'"
		ip route del default
	fi
	ip route add default via "$router" dev "${MAIN_NETIF}"
	echo "SLX_DHCP_GATEWAY='$router'" >> "$NETWORK_CONF"
fi

##
## ADDITIONAL NETWORK CONFIGURATION
##
## > DNS, domain, hostname

rm -f -- "/etc/resolv.conf"

reverse_lookup() {
	[ -z "$dns" ] && return
	[ -z "$1" ] && return
	timeout 3 nslookup "$1" | awk '{
		if ($2 == "name") { print gensub("\\.$", "", 1, $4); exit; }
		if ($1 == "Name:") { ok = 1 }
		if (ok && $1 == "Address") { print gensub("\\.$", "", 1, $4); exit; }
	}'
}

echo "# From DHCP in stage 3.1" >> "$NETWORK_CONF"

# DNS/domain?
if [ -n "$dns" ]; then
	log "DNS servers: $dns"
	echo "SLX_DNS='$dns'" >> "$NETWORK_CONF"
	for srv in $dns; do
		echo "nameserver $srv" >> "/etc/resolv.conf"
	done
else
	dns="$( < /etc/resolv.conf  awk '$1 == "nameserver" {printf "%s ", $2}' )"
fi

# always check DNS
log "checking reverse DNS record for this host"
[ -n "$fqdn" ] && [[ "$fqdn" != *.* ]] && fqdn=
[ -z "$fqdn" ] && fqdn="$( reverse_lookup "$ip" )"
[ -z "$fqdn" ] && [ -n "$hostname" ] && [ -n "$domain" ] && fqdn="${hostname}.${domain}"

# retry DNS one time
if [ -z "$fqdn" ]; then
	log "found no way to generate FQDN, trying reverse lookup one more time"
	sleep 1
	fqdn="$( reverse_lookup "$ip" )"
fi
if [ -n "$fqdn" ]; then
	fqdn_hostname="${fqdn%%.*}"
	fqdn_domain="${fqdn#*.}"
fi

if [ -z "$hostname" ] && [ -n "$fqdn_hostname" ]; then
	hostname="${fqdn_hostname}"
	log "using hostname from DNS, as DHCP didn't supply one"
fi
if [ -z "$hostname" ] && [ -n "$SLX_PXE_HOSTNAME" ]; then
	hostname="$SLX_PXE_HOSTNAME"
	log "using hostname from KCL, as DHCP/DNS didn't supply one"
fi
if [ -z "$hostname" ]; then
	hostname="noname-${ip//./-}"
	log "got no hostname via DHCP, DNS or KCL, using fallback '$hostname'"
fi
if [ -z "$domain" ] && [ -n "$fqdn_domain" ]; then
	domain="${fqdn_domain}"
	log "using domain from DNS, as DHCP didn't supply one"
fi

domain="${domain%% *}" # in case domain is a list, some DHCP servers did that in the past instead of using search

# Normalize to lowercase
for var in hostname domain fqdn search fqdn_hostname fqdn_domain SLX_PXE_HOSTNAME; do
	declare "$var"="${!var~~}"
done

# Add domain to list of search domains if not in there yet
if [ -n "$domain" ] && [ -n "$search" ]; then
	FOUND=no
	for sd in $search; do
		[ "$sd" = "$domain" ] && FOUND=yes
	done
	[ "$FOUND" = "no" ] && search="$domain $search"
elif [ -n "$domain" ]; then
	search="$domain"
fi

# Write out
if [ -n "$domain" ]; then
	echo "domain $domain" >> "/etc/resolv.conf"
	echo "SLX_NET_DOMAIN='$domain'" >> "$NETWORK_CONF"
fi

if [ -n "$search" ]; then
	echo "search $search" >> "/etc/resolv.conf"
	echo "SLX_NET_SEARCH='$search'" >> "$NETWORK_CONF"
fi

if [ -n "$ntpsrv" ]; then
	echo "SLX_DHCP_NTP='$ntpsrv'" >> "$NETWORK_CONF"
fi

declare -a localnames=()
[ -n "$fqdn" ] && localnames+=( "$fqdn" )
[ -n "$hostname" ] && localnames+=( "$hostname" )
[ -n "$fqdn_hostname" ] && [ "$hostname" != "$fqdn_hostname" ] && localnames+=( "$fqdn_hostname" )
[ -n "$SLX_PXE_HOSTNAME" ] && [ "$hostname" != "$SLX_PXE_HOSTNAME" ] && localnames+=( "$SLX_PXE_HOSTNAME" )

{
echo "127.0.0.1 localhost"
echo "127.0.1.1 ${localnames[*]}"
} > "/etc/hosts"

log "setting hostname $hostname, FQDN $fqdn"
echo "$hostname" > "/proc/sys/kernel/hostname"
echo "$hostname" > "/etc/hostname"
echo "SLX_HOSTNAME='$hostname'" >> "$NETWORK_CONF"

touch /.network
set +x
} {BASH_XTRACEFD}> "/run/openslx/initramfs-udhcpc.log.$$"