summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJerry Jelinek <jerry.jelinek@joyent.com>2011-07-19 10:01:31 -0700
committerJerry Jelinek <jerry.jelinek@joyent.com>2011-07-19 10:01:31 -0700
commitffdb5ae22c9fd339e1f5d32ee049056ad2799907 (patch)
treeb216b8bb54cc8edeab82a5f6ebdff2251343f745
parent21ed1342ea82dee06f258e8f85fe55161e7b8ce4 (diff)
downloadillumos-joyent-ffdb5ae22c9fd339e1f5d32ee049056ad2799907.tar.gz
OS-504 kvm brand hook needs to create vnics
-rwxr-xr-xusr/src/lib/brand/kvm/zone/statechange.ksh177
1 files changed, 176 insertions, 1 deletions
diff --git a/usr/src/lib/brand/kvm/zone/statechange.ksh b/usr/src/lib/brand/kvm/zone/statechange.ksh
index 2b4da6f6dd..59a474e292 100755
--- a/usr/src/lib/brand/kvm/zone/statechange.ksh
+++ b/usr/src/lib/brand/kvm/zone/statechange.ksh
@@ -84,7 +84,182 @@ unlock_file()
#
setup_net()
{
- touch $ZONEPATH/netsetup
+ # XXX old code, is this still needed by anything?
+ # touch $ZONEPATH/netsetup
+
+ for nic in $_ZONECFG_net_resources
+ do
+ # Get simplified versions of the network config. variables.
+ address=$(eval echo \$_ZONECFG_net_${nic}_address)
+ global_nic=$(eval echo \$_ZONECFG_net_${nic}_global_nic)
+ mac_addr=$(eval echo \$_ZONECFG_net_${nic}_mac_addr)
+ vlan_id=$(eval echo \$_ZONECFG_net_${nic}_vlan_id)
+ blocked_outgoing_ports=$(eval \
+ echo \$_ZONECFG_net_${nic}_blocked_outgoing_ports)
+ zone_ip=$(eval echo \$_ZONECFG_net_${nic}_ip)
+
+ # If address set, must be a shared stack zone
+ [[ -n $address ]] && exit 0
+
+ # If no global-nic, must be a dedicated physical NIC instead
+ # of a vnic
+ [[ -z $global_nic ]] && continue
+
+ orig_global=$global_nic
+ global_nic=$(eval echo \$SYSINFO_NIC_${orig_global})
+
+ # For backwards compatibility with the other parts of the
+ # system, check if this zone already has this vnic setup.
+ # If so, move on to the next vnic.
+ dladm show-vnic -p -o LINK -z $ZONENAME $nic >/dev/null 2>&1
+ (( $? == 0 )) && continue
+
+ if [[ -z $global_nic ]]; then
+ echo "undefined VNIC $nic " \
+ "(global NIC $orig_global)"
+ logger -p daemon.err "zone $ZONENAME " \
+ "undefined VNIC $nic (global NIC $orig_global)"
+ exit 1
+ fi
+
+ lock_file
+
+ #
+ # Create the vnic.
+ #
+
+ opt_str="-p zone=$ZONENAME"
+ [[ -n $mac_addr ]] && opt_str="$opt_str -m $mac_addr"
+
+ [[ -n $vlan_id && $vlan_id != 0 ]] && \
+ opt_str="$opt_str -v $vlan_id"
+
+ #
+ # Creating a VNIC in a zone is a multi-step process internally.
+ # This means there is a short window where the VNIC exists in
+ # the global zone and that could lead to a race condition if
+ # two zones boot at the same time with the same VNIC name. Use
+ # a temp. name to create the VNIC then rename it to have the
+ # correct name.
+ #
+ tname=tmp$$0
+ dout=`dladm create-vnic -t -l $global_nic $opt_str $tname 2>&1`
+ if (( $? != 0 )); then
+ print -f "error creating VNIC %s (global NIC %s)\n" \
+ "$nic" "$orig_global"
+ print -f "msg: %s\n" "$dout"
+ logger -p daemon.err "zone $ZONENAME error creating " \
+ "VNIC $nic (global NIC $orig_global $global_nic)"
+ logger -p daemon.err "msg: $dout"
+ logger -p daemon.err "Failed cmd: dladm create-vnic " \
+ "-t -l $global_nic $opt_str $tname"
+
+ # Show more info if dup MAC addr.
+ echo $dout | egrep -s "MAC address is already in use"
+ if (( $? == 0 )); then
+ entry=`dladm show-vnic -olink,macaddress,zone \
+ | nawk -v addr=$mac_addr '{
+ if ($2 == addr)
+ print $0
+ }'`
+ if [[ -n $entry ]]; then
+ print -f "LINK\tMACADDRESS\tZONE\n"
+ print -f "%s\n" "$entry"
+ fi
+ fi
+ exit 1
+ fi
+ dladm rename-link -z $ZONENAME $tname $nic
+ if (( $? != 0 )); then
+ echo "error renaming VNIC $tname $nic"
+ logger -p daemon.err "zone $ZONENAME error renaming " \
+ "VNIC $tname $nic"
+ exit 1
+ fi
+
+ if [[ -z $mac_addr ]]; then
+ # There was no assigned mac address
+
+ # Get newly assigned mac address.
+ mac_addr=$(dladm show-vnic -z $ZONENAME -p -o \
+ MACADDRESS ${nic})
+
+ # Save newly assigned mac address
+ [[ -n $mac_addr ]] && zonecfg -z $ZONENAME \
+ "select net physical=$nic; " \
+ "set mac-addr=$mac_addr; end; exit"
+ fi
+
+ # Enable full antispoof
+ spoof_opts="ip-nospoof,mac-nospoof,restricted,dhcp-nospoof"
+ dladm set-linkprop -t -z $ZONENAME -p \
+ "protection=${spoof_opts}" ${nic}
+ if (( $? != 0 )); then
+ echo "error setting VNIC protection $nic $spoof_opts"
+ logger -p daemon.err "zone $ZONENAME error setting " \
+ "VNIC protection $nic $spoof_opts"
+ exit 1
+ fi
+
+ if [[ -n "${zone_ip}" ]]; then
+ dladm set-linkprop -t -z $ZONENAME \
+ -p "allowed-ips=${zone_ip}" ${nic}
+ if (( $? != 0 )); then
+ echo "error setting VNIC allowed-ip " \
+ "$nic $zone_ip"
+ logger -p daemon.err "zone $ZONENAME " \
+ "error setting VNIC allowed-ip " \
+ "$nic $zone_ip"
+ exit 1
+ fi
+ fi
+
+ # If on VMWare and we have external IPs, create a bridge to
+ # allow zones to reach the external gateway
+ if [[ ${orig_global} == "external" && \
+ "${SYSINFO_Product}" == "VMware Virtual Platform" ]]; then
+ dladm show-bridge -p -o BRIDGE vmwareextbr \
+ >/dev/null 2>&1
+ if (( $? != 0 )); then
+ dladm create-bridge -l ${SYSINFO_NIC_external} \
+ vmwareextbr
+ if (( $? != 0 )); then
+ echo "error creating bridge vmwareextbr"
+ logger -p daemon.err "error creating " \
+ "bridge vmwareextbr"
+ exit 1
+ fi
+ fi
+ fi
+
+ if [[ -n $blocked_outgoing_ports ]]; then
+ OLDIFS=$IFS
+ IFS=,
+ for port in $blocked_outgoing_ports; do
+ # br='block remote'. Flow names should be < 31
+ # chars in length so that they get unique
+ # kstats.
+ # Use the VNIC mac addr. to generate a unique
+ # name.
+ mac_addr=`dladm show-vnic -z $ZONENAME -p \
+ -o MACADDRESS $nic | tr ':' '_'`
+ flowadm add-flow -t -l $nic -z $ZONENAME \
+ -a transport=tcp,remote_port=$port \
+ -p maxbw=0 f${mac_addr}_br_${port}
+ if (( $? != 0 )); then
+ echo "error adding flow " \
+ "$nic f${mac_addr}_br_${port}"
+ logger -p daemon.err "zone $ZONENAME " \
+ "error adding flow " \
+ "$nic f${mac_addr}_br_${port}"
+ exit 1
+ fi
+ done
+ IFS=$OLDIFS
+ fi
+
+ unlock_file
+ done
}
#