17
17
18
18
package com .cloud .network ;
19
19
20
- import java .util .List ;
21
20
import java .util .Map ;
22
21
23
22
import javax .inject .Inject ;
24
23
import javax .naming .ConfigurationException ;
25
24
25
+ import com .cloud .vm .NicProfile ;
26
+ import com .googlecode .ipv6 .IPv6Address ;
26
27
import org .apache .cloudstack .framework .config .dao .ConfigurationDao ;
27
28
import org .apache .log4j .Logger ;
28
29
29
30
import com .cloud .configuration .Config ;
30
31
import com .cloud .dc .DataCenter ;
31
- import com .cloud .dc .DataCenterVO ;
32
- import com .cloud .dc .Vlan ;
33
- import com .cloud .dc .VlanVO ;
34
32
import com .cloud .dc .dao .DataCenterDao ;
35
33
import com .cloud .dc .dao .VlanDao ;
36
34
import com .cloud .exception .InsufficientAddressCapacityException ;
39
37
import com .cloud .network .Network .IpAddresses ;
40
38
import com .cloud .network .dao .IPAddressDao ;
41
39
import com .cloud .network .dao .IPAddressVO ;
42
- import com .cloud .network .dao .NetworkDao ;
43
40
import com .cloud .network .dao .UserIpv6AddressDao ;
44
41
import com .cloud .user .Account ;
45
42
import com .cloud .utils .NumbersUtil ;
46
43
import com .cloud .utils .component .ManagerBase ;
47
44
import com .cloud .utils .db .DB ;
48
- import com .cloud .utils .exception .CloudRuntimeException ;
49
45
import com .cloud .utils .net .NetUtils ;
50
46
import com .cloud .vm .dao .NicSecondaryIpDao ;
51
47
import com .cloud .vm .dao .NicSecondaryIpVO ;
@@ -65,8 +61,6 @@ public class Ipv6AddressManagerImpl extends ManagerBase implements Ipv6AddressMa
65
61
@ Inject
66
62
UserIpv6AddressDao _ipv6Dao ;
67
63
@ Inject
68
- NetworkDao _networkDao ;
69
- @ Inject
70
64
ConfigurationDao _configDao ;
71
65
@ Inject
72
66
IpAddressManager ipAddressManager ;
@@ -83,87 +77,6 @@ public boolean configure(String name, Map<String, Object> params) throws Configu
83
77
return true ;
84
78
}
85
79
86
- @ Override
87
- public UserIpv6Address assignDirectIp6Address (long dcId , Account owner , Long networkId , String requestedIp6 ) throws InsufficientAddressCapacityException {
88
- Network network = _networkDao .findById (networkId );
89
- if (network == null ) {
90
- return null ;
91
- }
92
- List <VlanVO > vlans = _vlanDao .listVlansByNetworkId (networkId );
93
- if (vlans == null ) {
94
- s_logger .debug ("Cannot find related vlan attached to network " + networkId );
95
- return null ;
96
- }
97
- String ip = null ;
98
- Vlan ipVlan = null ;
99
- if (requestedIp6 == null ) {
100
- if (!_networkModel .areThereIPv6AddressAvailableInNetwork (networkId )) {
101
- throw new InsufficientAddressCapacityException ("There is no more address available in the network " + network .getName (), DataCenter .class ,
102
- network .getDataCenterId ());
103
- }
104
- for (Vlan vlan : vlans ) {
105
- if (!_networkModel .isIP6AddressAvailableInVlan (vlan .getId ())) {
106
- continue ;
107
- }
108
- ip = NetUtils .getIp6FromRange (vlan .getIp6Range ());
109
- int count = 0 ;
110
- while (_ipv6Dao .findByNetworkIdAndIp (networkId , ip ) != null ) {
111
- ip = NetUtils .getNextIp6InRange (ip , vlan .getIp6Range ());
112
- count ++;
113
- // It's an arbitrate number to prevent the infinite loop
114
- if (count > _ipv6RetryMax ) {
115
- ip = null ;
116
- break ;
117
- }
118
- }
119
- if (ip != null ) {
120
- ipVlan = vlan ;
121
- }
122
- }
123
- if (ip == null ) {
124
- throw new InsufficientAddressCapacityException ("Cannot find a usable IP in the network " + network .getName () + " after " + _ipv6RetryMax +
125
- "(network.ipv6.search.retry.max) times retry!" , DataCenter .class , network .getDataCenterId ());
126
- }
127
- } else {
128
- for (Vlan vlan : vlans ) {
129
- if (NetUtils .isIp6InRange (requestedIp6 , vlan .getIp6Range ())) {
130
- ipVlan = vlan ;
131
- break ;
132
- }
133
- }
134
- if (ipVlan == null ) {
135
- throw new CloudRuntimeException ("Requested IPv6 is not in the predefined range!" );
136
- }
137
- ip = requestedIp6 ;
138
- if (_ipv6Dao .findByNetworkIdAndIp (networkId , ip ) != null ) {
139
- throw new CloudRuntimeException ("The requested IP is already taken!" );
140
- }
141
- }
142
- DataCenterVO dc = _dcDao .findById (dcId );
143
- Long mac = dc .getMacAddress ();
144
- Long nextMac = mac + 1 ;
145
- dc .setMacAddress (nextMac );
146
- _dcDao .update (dc .getId (), dc );
147
-
148
- String macAddress = NetUtils .long2Mac (NetUtils .createSequenceBasedMacAddress (mac , NetworkModel .MACIdentifier .value ()));
149
- UserIpv6AddressVO ipVO = new UserIpv6AddressVO (ip , dcId , macAddress , ipVlan .getId ());
150
- ipVO .setPhysicalNetworkId (network .getPhysicalNetworkId ());
151
- ipVO .setSourceNetworkId (networkId );
152
- ipVO .setState (UserIpv6Address .State .Allocated );
153
- ipVO .setDomainId (owner .getDomainId ());
154
- ipVO .setAccountId (owner .getAccountId ());
155
- _ipv6Dao .persist (ipVO );
156
- return ipVO ;
157
- }
158
-
159
- @ Override
160
- public void revokeDirectIpv6Address (long networkId , String ip6Address ) {
161
- UserIpv6AddressVO ip = _ipv6Dao .findByNetworkIdAndIp (networkId , ip6Address );
162
- if (ip != null ) {
163
- _ipv6Dao .remove (ip .getId ());
164
- }
165
- }
166
-
167
80
/**
168
81
* Executes method {@link #acquireGuestIpv6Address(Network, String)} and returns the requested IPv6 (String) in case of successfully allocating the guest IPv6 address.
169
82
*/
@@ -260,4 +173,43 @@ protected boolean isIp6Taken(Network network, String requestedIpv6) {
260
173
return ip6Vo != null || nicSecondaryIpVO != null ;
261
174
}
262
175
176
+ /**
177
+ * Calculate the IPv6 Address the Instance will obtain using SLAAC and IPv6 EUI-64
178
+ *
179
+ * Linux, FreeBSD and Windows all calculate the same IPv6 address when configured properly. (SLAAC)
180
+ *
181
+ * Using Router Advertisements the routers in the network should announce the IPv6 CIDR which is configured
182
+ * for the network.
183
+ *
184
+ * It is up to the network administrator to make sure the IPv6 Routers in the network are sending out Router Advertisements
185
+ * with the correct IPv6 (Prefix, DNS, Lifetime) information.
186
+ *
187
+ * This way the NIC will be populated with a IPv6 address on which the Instance is reachable.
188
+ *
189
+ * This method calculates the IPv6 address the Instance will obtain and updates the Nic object with the correct
190
+ * address information.
191
+ */
192
+ @ Override
193
+ public void setNicIp6Address (final NicProfile nic , final DataCenter dc , final Network network ) {
194
+ if (network .getIp6Gateway () != null ) {
195
+ if (nic .getIPv6Address () == null ) {
196
+ s_logger .debug ("Found IPv6 CIDR " + network .getIp6Cidr () + " for Network " + network );
197
+ nic .setIPv6Cidr (network .getIp6Cidr ());
198
+ nic .setIPv6Gateway (network .getIp6Gateway ());
199
+
200
+ IPv6Address ipv6addr = NetUtils .EUI64Address (network .getIp6Cidr (), nic .getMacAddress ());
201
+ s_logger .info ("Calculated IPv6 address " + ipv6addr + " using EUI-64 for NIC " + nic .getUuid ());
202
+ nic .setIPv6Address (ipv6addr .toString ());
203
+
204
+ if (nic .getIPv4Address () != null ) {
205
+ nic .setFormat (Networks .AddressFormat .DualStack );
206
+ } else {
207
+ nic .setFormat (Networks .AddressFormat .Ip6 );
208
+ }
209
+ }
210
+ nic .setIPv6Dns1 (dc .getIp6Dns1 ());
211
+ nic .setIPv6Dns2 (dc .getIp6Dns2 ());
212
+ }
213
+ }
214
+
263
215
}
0 commit comments