Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -743,6 +743,7 @@ public class ApiConstants {
public static final String LINMIN_APID = "linminapid";
public static final String DHCP_SERVER_TYPE = "dhcpservertype";
public static final String LINK_LOCAL_IP = "linklocalip";
public static final String LINK_LOCAL_IP6 = "linklocalip6";
public static final String LINK_LOCAL_MAC_ADDRESS = "linklocalmacaddress";
public static final String LINK_LOCAL_MAC_NETMASK = "linklocalnetmask";
public static final String LINK_LOCAL_NETWORK_ID = "linklocalnetworkid";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public class SystemVmResponse extends BaseResponseWithAnnotations {
@Param(description = "The Control IP address for the System VM")
private String linkLocalIp;

@SerializedName(ApiConstants.LINK_LOCAL_IP6)
@Param(description = "The Control IPv6 link-local address for the System VM, calculated from the link local MAC address", since = "4.23.0")
private String linkLocalIp6;

@SerializedName(ApiConstants.LINK_LOCAL_MAC_ADDRESS)
@Param(description = "The link local MAC address for the System VM")
private String linkLocalMacAddress;
Expand Down Expand Up @@ -427,6 +431,14 @@ public void setLinkLocalIp(String linkLocalIp) {
this.linkLocalIp = linkLocalIp;
}

public String getLinkLocalIp6() {
return linkLocalIp6;
}

public void setLinkLocalIp6(String linkLocalIp6) {
this.linkLocalIp6 = linkLocalIp6;
}

public String getLinkLocalMacAddress() {
return linkLocalMacAddress;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -510,6 +510,7 @@ public void createControlNetwork(String privBrName) {
Script.runSimpleBashScript("ip link set " + privBrName + " up");
Script.runSimpleBashScript("ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + privBrName);
}
enableBridgeIpv6LinkLocal(privBrName);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,7 @@ public void createControlNetwork(String privBrName) {
Script.runSimpleBashScript("ip link add " + privBrName + " type bridge; ip link set " + privBrName + " up");
Script.runSimpleBashScript("ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + privBrName, _timeout);
}
enableBridgeIpv6LinkLocal(privBrName);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -250,6 +250,7 @@ public void createControlNetwork(String privBrName) {
if (!isExistingBridge(privBrName)) {
Script.runSimpleBashScript("ovs-vsctl add-br " + privBrName + "; ip link set " + privBrName + " up; ip address add " + NetUtils.getLinkLocalAddressFromCIDR(_controlCidr) + " dev " + privBrName, _timeout);
}
enableBridgeIpv6LinkLocal(privBrName);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@

import com.cloud.agent.api.to.NicTO;
import com.cloud.exception.InternalErrorException;
import com.cloud.utils.script.Script;

public abstract class VifDriverBase implements VifDriver {

Expand Down Expand Up @@ -81,6 +82,18 @@ public boolean isExistingBridge(String bridgeName) {
return false;
}

/**
* Enable IPv6 on the control network bridge so the host can reach the
* IPv6 link-local address system VMs listen on. Only link-local is wanted,
* so Router Advertisements and SLAAC are disabled on the bridge.
*/
protected void enableBridgeIpv6LinkLocal(String bridgeName) {
logger.info("Enabling IPv6 link-local on bridge {}", bridgeName);
Script.runSimpleBashScript("sysctl -qw net.ipv6.conf." + bridgeName + ".accept_ra=0" +
" net.ipv6.conf." + bridgeName + ".autoconf=0" +
" net.ipv6.conf." + bridgeName + ".disable_ipv6=0");
}

protected static int getNetworkRateKbps(NicTO nic) {
if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) {
return nic.getNetworkRateMbps().intValue() * bitsPerMbpsToKbps;
Expand Down
3 changes: 3 additions & 0 deletions server/src/main/java/com/cloud/api/ApiResponseHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -1886,6 +1886,9 @@ public SystemVmResponse createSystemVmResponse(VirtualMachine vm) {
vmResponse.setLinkLocalIp(singleNicProfile.getIPv4Address());
vmResponse.setLinkLocalMacAddress(singleNicProfile.getMacAddress());
vmResponse.setLinkLocalNetmask(singleNicProfile.getIPv4Netmask());
if (singleNicProfile.getMacAddress() != null) {
vmResponse.setLinkLocalIp6(NetUtils.ipv6LinkLocal(singleNicProfile.getMacAddress()).toString());
}
} else if (network.getTrafficType() == TrafficType.Public) {
vmResponse.setPublicIp(singleNicProfile.getIPv4Address());
vmResponse.setPublicMacAddress(singleNicProfile.getMacAddress());
Expand Down
4 changes: 4 additions & 0 deletions systemvm/debian/opt/cloud/bin/cs/CsNetfilter.py
Original file line number Diff line number Diff line change
Expand Up @@ -232,6 +232,10 @@ def add_ip6_chain(self, address_family, table, chain, hook, action):
if hook == "input" or hook == "output":
CsHelper.execute("nft add rule %s %s %s icmpv6 type { echo-request, echo-reply, \
nd-neighbor-solicit, nd-router-advert, nd-neighbor-advert } accept" % (address_family, table, chain))
if hook == "input":
# sshd listens on the IPv6 link-local address of the control interface,
# only allow this over link-local so no global address can reach it
CsHelper.execute("nft add rule %s %s %s ip6 saddr fe80::/10 ip6 daddr fe80::/10 tcp dport 3922 accept" % (address_family, table, chain))
if hook == "input" or hook == "forward":
CsHelper.execute("nft add rule %s %s %s ct state established,related accept" % (address_family, table, chain))

Expand Down
34 changes: 33 additions & 1 deletion systemvm/debian/opt/cloud/bin/setup/common.sh
Original file line number Diff line number Diff line change
Expand Up @@ -573,10 +573,42 @@ setup_dnsmasq() {
fi
}

enable_ipv6_link_local() {
local eth=$1
log_it "Enabling IPv6 link-local on interface $eth"
# Generate the link-local address with EUI-64 based on the MAC address so
# the address can be calculated by the Management Server
sysctl -w net.ipv6.conf.${eth}.addr_gen_mode=0
# Only a link-local address is wanted, no SLAAC/RA configuration
sysctl -w net.ipv6.conf.${eth}.accept_ra=0
sysctl -w net.ipv6.conf.${eth}.autoconf=0
sysctl -w net.ipv6.conf.${eth}.disable_ipv6=0

# Wait for Duplicate Address Detection to complete so the address can be bound
LINK_LOCAL_IP6=""
local i
for i in $(seq 1 10); do
LINK_LOCAL_IP6=$(ip -6 addr show dev ${eth} scope link -tentative | grep -Po '(?<=inet6 )fe80:[0-9a-f:]+' | head -1)
[ -n "$LINK_LOCAL_IP6" ] && break
sleep 1
done

if [ -n "$LINK_LOCAL_IP6" ]; then
log_it "Interface $eth has IPv6 link-local address $LINK_LOCAL_IP6"
else
log_it "No IPv6 link-local address appeared on interface $eth"
fi
}

setup_sshd(){
local ip=$1
local eth=$2
[ -f /etc/ssh/sshd_config ] && sed -i -e "s/^[#]*ListenAddress.*$/ListenAddress $ip/" /etc/ssh/sshd_config
[ -f /etc/ssh/sshd_config ] && sed -i -e "/^ListenAddress fe80/d" -e "s/^[#]*ListenAddress.*$/ListenAddress $ip/" /etc/ssh/sshd_config
enable_ipv6_link_local $eth
if [ -n "$LINK_LOCAL_IP6" ]; then
log_it "Configuring sshd to also listen on ${LINK_LOCAL_IP6}%${eth}"
sed -i -e "/^ListenAddress $ip$/a ListenAddress ${LINK_LOCAL_IP6}%${eth}" /etc/ssh/sshd_config
fi
sed -i "/3922/s/eth./$eth/" /etc/iptables/rules.v4
}

Expand Down
1 change: 1 addition & 0 deletions ui/public/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1599,6 +1599,7 @@
"label.link": "Link",
"label.link.domain.to.ldap": "Link domain to LDAP",
"label.linklocalip": "Link-local/Control IP address",
"label.linklocalip6": "Link-local/Control IPv6 address",
"label.linux": "Linux",
"label.list.ciscoasa1000v": "ASA 1000v",
"label.list.ciscovnmc": "Cisco VNMC",
Expand Down
4 changes: 2 additions & 2 deletions ui/src/config/section/infra/systemVms.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ export default {
docHelp: 'adminguide/systemvm.html',
permission: ['listSystemVms'],
searchFilters: ['name', 'zoneid', 'podid', 'hostid', 'systemvmtype', 'storageid', 'arch'],
columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'version', 'hostname', 'arch', 'zonename'],
details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'gateway', 'hostname', 'arch', 'version', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable', 'hostcontrolstate', 'storageip'],
columns: ['name', 'state', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'linklocalip6', 'version', 'hostname', 'arch', 'zonename'],
details: ['name', 'id', 'agentstate', 'systemvmtype', 'publicip', 'privateip', 'linklocalip', 'linklocalip6', 'gateway', 'hostname', 'arch', 'version', 'zonename', 'created', 'activeviewersessions', 'isdynamicallyscalable', 'hostcontrolstate', 'storageip'],
resourceType: 'SystemVm',
filters: () => {
const filters = ['starting', 'running', 'stopping', 'stopped', 'destroyed', 'expunging', 'migrating', 'error', 'unknown', 'shutdown']
Expand Down
Loading