Committed by
Gerrit Code Review
Make some DHCP options and host discovery configurable
- Added broadcast option - Made host discovery from DHCP configurable - Some code cleanups Change-Id: I42191c2fd17ef309c73a5382730d708686b835cd (cherry picked from commit 04b1fe9a)
Showing
11 changed files
with
182 additions
and
133 deletions
... | @@ -15,7 +15,6 @@ | ... | @@ -15,7 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.cordvtn.impl; | 16 | package org.onosproject.cordvtn.impl; |
17 | 17 | ||
18 | -import com.google.common.collect.Lists; | ||
19 | import com.google.common.collect.Sets; | 18 | import com.google.common.collect.Sets; |
20 | import org.apache.felix.scr.annotations.Activate; | 19 | import org.apache.felix.scr.annotations.Activate; |
21 | import org.apache.felix.scr.annotations.Component; | 20 | import org.apache.felix.scr.annotations.Component; |
... | @@ -34,6 +33,7 @@ import org.onosproject.cordvtn.api.Instance; | ... | @@ -34,6 +33,7 @@ import org.onosproject.cordvtn.api.Instance; |
34 | import org.onosproject.core.ApplicationId; | 33 | import org.onosproject.core.ApplicationId; |
35 | import org.onosproject.core.CoreService; | 34 | import org.onosproject.core.CoreService; |
36 | import org.onosproject.dhcp.DhcpService; | 35 | import org.onosproject.dhcp.DhcpService; |
36 | +import org.onosproject.dhcp.IpAssignment; | ||
37 | import org.onosproject.mastership.MastershipService; | 37 | import org.onosproject.mastership.MastershipService; |
38 | import org.onosproject.net.ConnectPoint; | 38 | import org.onosproject.net.ConnectPoint; |
39 | import org.onosproject.net.DefaultAnnotations; | 39 | import org.onosproject.net.DefaultAnnotations; |
... | @@ -70,7 +70,7 @@ import org.onosproject.xosclient.api.XosAccess; | ... | @@ -70,7 +70,7 @@ import org.onosproject.xosclient.api.XosAccess; |
70 | import org.onosproject.xosclient.api.XosClientService; | 70 | import org.onosproject.xosclient.api.XosClientService; |
71 | import org.slf4j.Logger; | 71 | import org.slf4j.Logger; |
72 | 72 | ||
73 | -import java.util.List; | 73 | +import java.util.Date; |
74 | import java.util.Map; | 74 | import java.util.Map; |
75 | import java.util.Objects; | 75 | import java.util.Objects; |
76 | import java.util.Set; | 76 | import java.util.Set; |
... | @@ -82,6 +82,8 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -82,6 +82,8 @@ import static com.google.common.base.Preconditions.checkNotNull; |
82 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; | 82 | import static java.util.concurrent.Executors.newSingleThreadScheduledExecutor; |
83 | import static org.onlab.util.Tools.groupedThreads; | 83 | import static org.onlab.util.Tools.groupedThreads; |
84 | import static org.onosproject.cordvtn.api.Instance.*; | 84 | import static org.onosproject.cordvtn.api.Instance.*; |
85 | +import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced; | ||
86 | +import static org.onosproject.xosclient.api.VtnService.NetworkType.MANAGEMENT; | ||
85 | import static org.onosproject.xosclient.api.VtnService.NetworkType.PRIVATE; | 87 | import static org.onosproject.xosclient.api.VtnService.NetworkType.PRIVATE; |
86 | import static org.slf4j.LoggerFactory.getLogger; | 88 | import static org.slf4j.LoggerFactory.getLogger; |
87 | 89 | ||
... | @@ -97,6 +99,7 @@ public class CordVtnInstanceManager extends AbstractProvider implements HostProv | ... | @@ -97,6 +99,7 @@ public class CordVtnInstanceManager extends AbstractProvider implements HostProv |
97 | private static final String XOS_ACCESS_ERROR = "XOS access is not configured"; | 99 | private static final String XOS_ACCESS_ERROR = "XOS access is not configured"; |
98 | private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured"; | 100 | private static final String OPENSTACK_ACCESS_ERROR = "OpenStack access is not configured"; |
99 | private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8"); | 101 | private static final Ip4Address DEFAULT_DNS = Ip4Address.valueOf("8.8.8.8"); |
102 | + private static final int DHCP_INFINITE_LEASE = -1; | ||
100 | 103 | ||
101 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 104 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
102 | protected CoreService coreService; | 105 | protected CoreService coreService; |
... | @@ -273,7 +276,6 @@ public class CordVtnInstanceManager extends AbstractProvider implements HostProv | ... | @@ -273,7 +276,6 @@ public class CordVtnInstanceManager extends AbstractProvider implements HostProv |
273 | arpProxy.addGateway(service.serviceIp(), privateGatewayMac); | 276 | arpProxy.addGateway(service.serviceIp(), privateGatewayMac); |
274 | arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(instance)); | 277 | arpProxy.sendGratuitousArpForGateway(service.serviceIp(), Sets.newHashSet(instance)); |
275 | } | 278 | } |
276 | - | ||
277 | if (!instance.isNestedInstance()) { | 279 | if (!instance.isNestedInstance()) { |
278 | registerDhcpLease(instance, service); | 280 | registerDhcpLease(instance, service); |
279 | } | 281 | } |
... | @@ -295,17 +297,25 @@ public class CordVtnInstanceManager extends AbstractProvider implements HostProv | ... | @@ -295,17 +297,25 @@ public class CordVtnInstanceManager extends AbstractProvider implements HostProv |
295 | } | 297 | } |
296 | 298 | ||
297 | private void registerDhcpLease(Instance instance, VtnService service) { | 299 | private void registerDhcpLease(Instance instance, VtnService service) { |
298 | - List<Ip4Address> options = Lists.newArrayList(); | 300 | + Ip4Address broadcast = Ip4Address.makeMaskedAddress( |
299 | - options.add(Ip4Address.makeMaskPrefix(service.subnet().prefixLength())); | 301 | + instance.ipAddress(), |
300 | - options.add(service.serviceIp().getIp4Address()); | 302 | + service.subnet().prefixLength()); |
301 | - options.add(service.serviceIp().getIp4Address()); | 303 | + |
302 | - options.add(DEFAULT_DNS); | 304 | + IpAssignment.Builder ipBuilder = IpAssignment.builder() |
305 | + .ipAddress(instance.ipAddress()) | ||
306 | + .leasePeriod(DHCP_INFINITE_LEASE) | ||
307 | + .timestamp(new Date()) | ||
308 | + .subnetMask(Ip4Address.makeMaskPrefix(service.subnet().prefixLength())) | ||
309 | + .broadcast(broadcast) | ||
310 | + .domainServer(DEFAULT_DNS) | ||
311 | + .assignmentStatus(Option_RangeNotEnforced); | ||
312 | + | ||
313 | + if (service.networkType() != MANAGEMENT) { | ||
314 | + ipBuilder = ipBuilder.routerAddress(service.serviceIp().getIp4Address()); | ||
315 | + } | ||
303 | 316 | ||
304 | log.debug("Set static DHCP mapping for {} {}", instance.mac(), instance.ipAddress()); | 317 | log.debug("Set static DHCP mapping for {} {}", instance.mac(), instance.ipAddress()); |
305 | - dhcpService.setStaticMapping(instance.mac(), | 318 | + dhcpService.setStaticMapping(instance.mac(), ipBuilder.build()); |
306 | - instance.ipAddress(), | ||
307 | - true, | ||
308 | - options); | ||
309 | } | 319 | } |
310 | 320 | ||
311 | private VtnService getVtnService(VtnServiceId serviceId) { | 321 | private VtnService getVtnService(VtnServiceId serviceId) { | ... | ... |
... | @@ -19,7 +19,6 @@ import org.onlab.packet.Ip4Address; | ... | @@ -19,7 +19,6 @@ import org.onlab.packet.Ip4Address; |
19 | import org.onlab.packet.MacAddress; | 19 | import org.onlab.packet.MacAddress; |
20 | import org.onosproject.net.HostId; | 20 | import org.onosproject.net.HostId; |
21 | 21 | ||
22 | -import java.util.List; | ||
23 | import java.util.Map; | 22 | import java.util.Map; |
24 | 23 | ||
25 | 24 | ||
... | @@ -58,16 +57,12 @@ public interface DhcpService { | ... | @@ -58,16 +57,12 @@ public interface DhcpService { |
58 | 57 | ||
59 | /** | 58 | /** |
60 | * Registers a static IP mapping with the DHCP Server. | 59 | * Registers a static IP mapping with the DHCP Server. |
61 | - * Supports rangeNotEnforced option | ||
62 | * | 60 | * |
63 | - * @param macID macID of the client | 61 | + * @param macAddress mac address to have a given ip assignment |
64 | - * @param ipAddress IP Address requested for the client | 62 | + * @param ipRequest ip address and dhcp options |
65 | - * @param rangeNotEnforced true if rangeNotEnforced was set and the mapping will be eternal | ||
66 | - * @param addressList subnetMask, DHCP/Router/DNS IP Addresses if rangeNotEnforced was set | ||
67 | * @return true if the mapping was successfully added, false otherwise | 63 | * @return true if the mapping was successfully added, false otherwise |
68 | */ | 64 | */ |
69 | - boolean setStaticMapping(MacAddress macID, Ip4Address ipAddress, boolean rangeNotEnforced, | 65 | + boolean setStaticMapping(MacAddress macAddress, IpAssignment ipRequest); |
70 | - List<Ip4Address> addressList); | ||
71 | 66 | ||
72 | /** | 67 | /** |
73 | * Removes a static IP mapping with the DHCP Server. | 68 | * Removes a static IP mapping with the DHCP Server. | ... | ... |
... | @@ -19,7 +19,6 @@ import org.onlab.packet.Ip4Address; | ... | @@ -19,7 +19,6 @@ import org.onlab.packet.Ip4Address; |
19 | import org.onlab.packet.MacAddress; | 19 | import org.onlab.packet.MacAddress; |
20 | import org.onosproject.net.HostId; | 20 | import org.onosproject.net.HostId; |
21 | 21 | ||
22 | -import java.util.List; | ||
23 | import java.util.Map; | 22 | import java.util.Map; |
24 | 23 | ||
25 | 24 | ||
... | @@ -41,7 +40,7 @@ public interface DhcpStore { | ... | @@ -41,7 +40,7 @@ public interface DhcpStore { |
41 | * | 40 | * |
42 | * @param hostId Host ID of the client requesting an IP | 41 | * @param hostId Host ID of the client requesting an IP |
43 | * @param requestedIP requested IP address | 42 | * @param requestedIP requested IP address |
44 | - * @return IP address assigned to the Mac ID | 43 | + * @return IP address assigned to the Mac address; null if no available IP |
45 | */ | 44 | */ |
46 | Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP); | 45 | Ip4Address suggestIP(HostId hostId, Ip4Address requestedIP); |
47 | 46 | ||
... | @@ -50,14 +49,10 @@ public interface DhcpStore { | ... | @@ -50,14 +49,10 @@ public interface DhcpStore { |
50 | * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message. | 49 | * Assigns the requested IP to the Mac ID, in response to a DHCP REQUEST message. |
51 | * | 50 | * |
52 | * @param hostId Host Id of the client requesting an IP | 51 | * @param hostId Host Id of the client requesting an IP |
53 | - * @param ipAddr IP Address being requested | 52 | + * @param ipAssignment ip assignment |
54 | - * @param leaseTime Lease time offered by the server for this mapping | ||
55 | - * @param rangeNotEnforced true if rangeNotEnforced was set | ||
56 | - * @param addressList subnetMask, DHCP/Router/DNS IP Addresses if rangeNotEnforced was set | ||
57 | * @return returns true if the assignment was successful, false otherwise | 53 | * @return returns true if the assignment was successful, false otherwise |
58 | */ | 54 | */ |
59 | - boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean rangeNotEnforced, | 55 | + boolean assignIP(HostId hostId, IpAssignment ipAssignment); |
60 | - List<Ip4Address> addressList); | ||
61 | 56 | ||
62 | 57 | ||
63 | /** | 58 | /** |
... | @@ -92,21 +87,19 @@ public interface DhcpStore { | ... | @@ -92,21 +87,19 @@ public interface DhcpStore { |
92 | /** | 87 | /** |
93 | * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. | 88 | * Assigns the requested IP to the MAC ID (if available) for an indefinite period of time. |
94 | * | 89 | * |
95 | - * @param macID macID of the client | 90 | + * @param macAddress mac address of the client |
96 | - * @param ipAddr IP Address requested for the client | 91 | + * @param ipAssignment ip address and dhcp options requested for the client |
97 | - * @param rangeNotEnforced true if rangeNotEnforced was set | ||
98 | - * @param addressList subnetMask, DHCP/Router/DNS IP Addresses rangeNotEnforced was set | ||
99 | * @return true if the mapping was successfully registered, false otherwise | 92 | * @return true if the mapping was successfully registered, false otherwise |
100 | */ | 93 | */ |
101 | - boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean rangeNotEnforced, List<Ip4Address> addressList); | 94 | + boolean assignStaticIP(MacAddress macAddress, IpAssignment ipAssignment); |
102 | 95 | ||
103 | /** | 96 | /** |
104 | * Removes a static IP mapping associated with the given MAC ID from the DHCP Server. | 97 | * Removes a static IP mapping associated with the given MAC ID from the DHCP Server. |
105 | * | 98 | * |
106 | - * @param macID macID of the client | 99 | + * @param macAddress mac address of the client |
107 | * @return true if the mapping was successfully registered, false otherwise | 100 | * @return true if the mapping was successfully registered, false otherwise |
108 | */ | 101 | */ |
109 | - boolean removeStaticIP(MacAddress macID); | 102 | + boolean removeStaticIP(MacAddress macAddress); |
110 | 103 | ||
111 | /** | 104 | /** |
112 | * Returns the list of all the available IPs with the server. | 105 | * Returns the list of all the available IPs with the server. | ... | ... |
... | @@ -27,22 +27,15 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -27,22 +27,15 @@ import static com.google.common.base.Preconditions.checkNotNull; |
27 | */ | 27 | */ |
28 | public final class IpAssignment { | 28 | public final class IpAssignment { |
29 | 29 | ||
30 | + // TODO make some dhcp options optional | ||
30 | private final Ip4Address ipAddress; | 31 | private final Ip4Address ipAddress; |
31 | - | ||
32 | private final Date timestamp; | 32 | private final Date timestamp; |
33 | - | ||
34 | private final long leasePeriod; | 33 | private final long leasePeriod; |
35 | - | ||
36 | private final Ip4Address subnetMask; | 34 | private final Ip4Address subnetMask; |
37 | - | 35 | + private final Ip4Address broadcast; |
38 | private final Ip4Address dhcpServer; | 36 | private final Ip4Address dhcpServer; |
39 | - | ||
40 | private final Ip4Address routerAddress; | 37 | private final Ip4Address routerAddress; |
41 | - | ||
42 | private final Ip4Address domainServer; | 38 | private final Ip4Address domainServer; |
43 | - | ||
44 | - private final boolean rangeNotEnforced; | ||
45 | - | ||
46 | private final AssignmentStatus assignmentStatus; | 39 | private final AssignmentStatus assignmentStatus; |
47 | 40 | ||
48 | public enum AssignmentStatus { | 41 | public enum AssignmentStatus { |
... | @@ -52,8 +45,10 @@ public final class IpAssignment { | ... | @@ -52,8 +45,10 @@ public final class IpAssignment { |
52 | Option_Requested, | 45 | Option_Requested, |
53 | 46 | ||
54 | /** | 47 | /** |
55 | - * IP Assignment has been requested by a OpenStack. | 48 | + * Static IP Assignment with unregistered IP range. |
49 | + * This assignment can only be added or removed by set or remove static mapping. | ||
56 | */ | 50 | */ |
51 | + // TODO allow multiple IP ranges and remove this option | ||
57 | Option_RangeNotEnforced, | 52 | Option_RangeNotEnforced, |
58 | /** | 53 | /** |
59 | * IP has been assigned to a host. | 54 | * IP has been assigned to a host. |
... | @@ -70,30 +65,34 @@ public final class IpAssignment { | ... | @@ -70,30 +65,34 @@ public final class IpAssignment { |
70 | * Constructor for IPAssignment, where the ipAddress, the lease period, the timestamp | 65 | * Constructor for IPAssignment, where the ipAddress, the lease period, the timestamp |
71 | * and assignment status is supplied. | 66 | * and assignment status is supplied. |
72 | * | 67 | * |
73 | - * @param ipAddress | 68 | + * @param ipAddress ip address to assign |
74 | - * @param leasePeriod | 69 | + * @param leasePeriod lease period |
75 | - * @param timestamp | 70 | + * @param timestamp time stamp of the assignment |
76 | - * @param assignmentStatus | 71 | + * @param assignmentStatus statue of the assignment |
77 | - * @param subnetMask | 72 | + * @param subnetMask subnet mask of assigned ip range |
78 | - * @param dhcpServer | 73 | + * @param broadcast broadcast address |
79 | - * @param routerAddress | 74 | + * @param dhcpServer dhcp server address |
80 | - * @param domainServer | 75 | + * @param routerAddress router address |
81 | - * @param rangeNotEnforced | 76 | + * @param domainServer domain server address |
82 | */ | 77 | */ |
83 | private IpAssignment(Ip4Address ipAddress, | 78 | private IpAssignment(Ip4Address ipAddress, |
84 | long leasePeriod, | 79 | long leasePeriod, |
85 | Date timestamp, | 80 | Date timestamp, |
86 | - AssignmentStatus assignmentStatus, Ip4Address subnetMask, Ip4Address dhcpServer, | 81 | + AssignmentStatus assignmentStatus, |
87 | - Ip4Address routerAddress, Ip4Address domainServer, boolean rangeNotEnforced) { | 82 | + Ip4Address subnetMask, |
83 | + Ip4Address broadcast, | ||
84 | + Ip4Address dhcpServer, | ||
85 | + Ip4Address routerAddress, | ||
86 | + Ip4Address domainServer) { | ||
88 | this.ipAddress = ipAddress; | 87 | this.ipAddress = ipAddress; |
89 | this.leasePeriod = leasePeriod; | 88 | this.leasePeriod = leasePeriod; |
90 | this.timestamp = timestamp; | 89 | this.timestamp = timestamp; |
91 | this.assignmentStatus = assignmentStatus; | 90 | this.assignmentStatus = assignmentStatus; |
92 | this.subnetMask = subnetMask; | 91 | this.subnetMask = subnetMask; |
92 | + this.broadcast = broadcast; | ||
93 | this.dhcpServer = dhcpServer; | 93 | this.dhcpServer = dhcpServer; |
94 | this.routerAddress = routerAddress; | 94 | this.routerAddress = routerAddress; |
95 | this.domainServer = domainServer; | 95 | this.domainServer = domainServer; |
96 | - this.rangeNotEnforced = rangeNotEnforced; | ||
97 | } | 96 | } |
98 | 97 | ||
99 | /** | 98 | /** |
... | @@ -141,26 +140,51 @@ public final class IpAssignment { | ... | @@ -141,26 +140,51 @@ public final class IpAssignment { |
141 | return (int) this.leasePeriod * 1000; | 140 | return (int) this.leasePeriod * 1000; |
142 | } | 141 | } |
143 | 142 | ||
143 | + /** | ||
144 | + * Returns subnet mask of the IP assignment. | ||
145 | + * | ||
146 | + * @return subnet mask | ||
147 | + */ | ||
144 | public Ip4Address subnetMask() { | 148 | public Ip4Address subnetMask() { |
145 | return subnetMask; | 149 | return subnetMask; |
146 | } | 150 | } |
147 | 151 | ||
152 | + /** | ||
153 | + * Returns broadcast address of the IP assignment. | ||
154 | + * | ||
155 | + * @return broadcast address | ||
156 | + */ | ||
157 | + public Ip4Address broadcast() { | ||
158 | + return broadcast; | ||
159 | + } | ||
160 | + | ||
161 | + /** | ||
162 | + * Returns dhcp server of the IP assignment. | ||
163 | + * | ||
164 | + * @return dhcp server ip address | ||
165 | + */ | ||
148 | public Ip4Address dhcpServer() { | 166 | public Ip4Address dhcpServer() { |
149 | return dhcpServer; | 167 | return dhcpServer; |
150 | } | 168 | } |
151 | 169 | ||
170 | + /** | ||
171 | + * Returns router address of the IP assignment. | ||
172 | + * | ||
173 | + * @return router ip address | ||
174 | + */ | ||
152 | public Ip4Address routerAddress() { | 175 | public Ip4Address routerAddress() { |
153 | return routerAddress; | 176 | return routerAddress; |
154 | } | 177 | } |
155 | 178 | ||
179 | + /** | ||
180 | + * Returns domain server address. | ||
181 | + * | ||
182 | + * @return domain server ip address | ||
183 | + */ | ||
156 | public Ip4Address domainServer() { | 184 | public Ip4Address domainServer() { |
157 | return domainServer; | 185 | return domainServer; |
158 | } | 186 | } |
159 | 187 | ||
160 | - public boolean rangeNotEnforced() { | ||
161 | - return rangeNotEnforced; | ||
162 | - } | ||
163 | - | ||
164 | @Override | 188 | @Override |
165 | public String toString() { | 189 | public String toString() { |
166 | return MoreObjects.toStringHelper(getClass()) | 190 | return MoreObjects.toStringHelper(getClass()) |
... | @@ -169,10 +193,10 @@ public final class IpAssignment { | ... | @@ -169,10 +193,10 @@ public final class IpAssignment { |
169 | .add("lease", leasePeriod) | 193 | .add("lease", leasePeriod) |
170 | .add("assignmentStatus", assignmentStatus) | 194 | .add("assignmentStatus", assignmentStatus) |
171 | .add("subnetMask", subnetMask) | 195 | .add("subnetMask", subnetMask) |
196 | + .add("broadcast", broadcast) | ||
172 | .add("dhcpServer", dhcpServer) | 197 | .add("dhcpServer", dhcpServer) |
173 | .add("routerAddress", routerAddress) | 198 | .add("routerAddress", routerAddress) |
174 | .add("domainServer", domainServer) | 199 | .add("domainServer", domainServer) |
175 | - .add("rangeNotEnforced", rangeNotEnforced) | ||
176 | .toString(); | 200 | .toString(); |
177 | } | 201 | } |
178 | 202 | ||
... | @@ -201,25 +225,16 @@ public final class IpAssignment { | ... | @@ -201,25 +225,16 @@ public final class IpAssignment { |
201 | public static final class Builder { | 225 | public static final class Builder { |
202 | 226 | ||
203 | private Ip4Address ipAddress; | 227 | private Ip4Address ipAddress; |
204 | - | ||
205 | private Date timeStamp; | 228 | private Date timeStamp; |
206 | - | ||
207 | private long leasePeriod; | 229 | private long leasePeriod; |
208 | - | ||
209 | private AssignmentStatus assignmentStatus; | 230 | private AssignmentStatus assignmentStatus; |
210 | - | ||
211 | private Ip4Address subnetMask; | 231 | private Ip4Address subnetMask; |
212 | - | 232 | + private Ip4Address broadcast; |
213 | private Ip4Address dhcpServer; | 233 | private Ip4Address dhcpServer; |
214 | - | ||
215 | - private Ip4Address domainServer; | ||
216 | - | ||
217 | private Ip4Address routerAddress; | 234 | private Ip4Address routerAddress; |
218 | - | 235 | + private Ip4Address domainServer; |
219 | - private boolean rangeNotEnforced = false; | ||
220 | 236 | ||
221 | private Builder() { | 237 | private Builder() { |
222 | - | ||
223 | } | 238 | } |
224 | 239 | ||
225 | private Builder(IpAssignment ipAssignment) { | 240 | private Builder(IpAssignment ipAssignment) { |
... | @@ -227,12 +242,24 @@ public final class IpAssignment { | ... | @@ -227,12 +242,24 @@ public final class IpAssignment { |
227 | timeStamp = ipAssignment.timestamp(); | 242 | timeStamp = ipAssignment.timestamp(); |
228 | leasePeriod = ipAssignment.leasePeriod(); | 243 | leasePeriod = ipAssignment.leasePeriod(); |
229 | assignmentStatus = ipAssignment.assignmentStatus(); | 244 | assignmentStatus = ipAssignment.assignmentStatus(); |
245 | + subnetMask = ipAssignment.subnetMask(); | ||
246 | + broadcast = ipAssignment.broadcast(); | ||
247 | + dhcpServer = ipAssignment.dhcpServer(); | ||
248 | + routerAddress = ipAssignment.routerAddress(); | ||
249 | + domainServer = ipAssignment.domainServer(); | ||
230 | } | 250 | } |
231 | 251 | ||
232 | public IpAssignment build() { | 252 | public IpAssignment build() { |
233 | validateInputs(); | 253 | validateInputs(); |
234 | - return new IpAssignment(ipAddress, leasePeriod, timeStamp, assignmentStatus, subnetMask, | 254 | + return new IpAssignment(ipAddress, |
235 | - dhcpServer, routerAddress, domainServer, rangeNotEnforced); | 255 | + leasePeriod, |
256 | + timeStamp, | ||
257 | + assignmentStatus, | ||
258 | + subnetMask, | ||
259 | + broadcast, | ||
260 | + dhcpServer, | ||
261 | + routerAddress, | ||
262 | + domainServer); | ||
236 | } | 263 | } |
237 | 264 | ||
238 | public Builder ipAddress(Ip4Address addr) { | 265 | public Builder ipAddress(Ip4Address addr) { |
... | @@ -260,6 +287,11 @@ public final class IpAssignment { | ... | @@ -260,6 +287,11 @@ public final class IpAssignment { |
260 | return this; | 287 | return this; |
261 | } | 288 | } |
262 | 289 | ||
290 | + public Builder broadcast(Ip4Address broadcast) { | ||
291 | + this.broadcast = broadcast; | ||
292 | + return this; | ||
293 | + } | ||
294 | + | ||
263 | public Builder dhcpServer(Ip4Address dhcpServer) { | 295 | public Builder dhcpServer(Ip4Address dhcpServer) { |
264 | this.dhcpServer = dhcpServer; | 296 | this.dhcpServer = dhcpServer; |
265 | return this; | 297 | return this; |
... | @@ -275,25 +307,12 @@ public final class IpAssignment { | ... | @@ -275,25 +307,12 @@ public final class IpAssignment { |
275 | return this; | 307 | return this; |
276 | } | 308 | } |
277 | 309 | ||
278 | - public Builder rangeNotEnforced(boolean rangeNotEnforced) { | ||
279 | - this.rangeNotEnforced = rangeNotEnforced; | ||
280 | - return this; | ||
281 | - } | ||
282 | - | ||
283 | - | ||
284 | private void validateInputs() { | 310 | private void validateInputs() { |
285 | checkNotNull(ipAddress, "IP Address must be specified"); | 311 | checkNotNull(ipAddress, "IP Address must be specified"); |
286 | checkNotNull(assignmentStatus, "Assignment Status must be specified"); | 312 | checkNotNull(assignmentStatus, "Assignment Status must be specified"); |
287 | checkNotNull(leasePeriod, "Lease Period must be specified"); | 313 | checkNotNull(leasePeriod, "Lease Period must be specified"); |
288 | checkNotNull(timeStamp, "Timestamp must be specified"); | 314 | checkNotNull(timeStamp, "Timestamp must be specified"); |
289 | 315 | ||
290 | - if (rangeNotEnforced) { | ||
291 | - checkNotNull(subnetMask, "subnetMask must be specified in case of rangeNotEnforced"); | ||
292 | - checkNotNull(dhcpServer, "dhcpServer must be specified in case of rangeNotEnforced"); | ||
293 | - checkNotNull(domainServer, "domainServer must be specified in case of rangeNotEnforced"); | ||
294 | - checkNotNull(routerAddress, "routerAddress must be specified in case of rangeNotEnforced"); | ||
295 | - } | ||
296 | - | ||
297 | switch (assignmentStatus) { | 316 | switch (assignmentStatus) { |
298 | case Option_Requested: | 317 | case Option_Requested: |
299 | case Option_RangeNotEnforced: | 318 | case Option_RangeNotEnforced: | ... | ... |
... | @@ -15,13 +15,17 @@ | ... | @@ -15,13 +15,17 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.dhcp.cli; | 16 | package org.onosproject.dhcp.cli; |
17 | 17 | ||
18 | -import com.google.common.collect.Lists; | ||
19 | import org.apache.karaf.shell.commands.Argument; | 18 | import org.apache.karaf.shell.commands.Argument; |
20 | import org.apache.karaf.shell.commands.Command; | 19 | import org.apache.karaf.shell.commands.Command; |
21 | import org.onlab.packet.Ip4Address; | 20 | import org.onlab.packet.Ip4Address; |
22 | import org.onlab.packet.MacAddress; | 21 | import org.onlab.packet.MacAddress; |
23 | import org.onosproject.cli.AbstractShellCommand; | 22 | import org.onosproject.cli.AbstractShellCommand; |
24 | import org.onosproject.dhcp.DhcpService; | 23 | import org.onosproject.dhcp.DhcpService; |
24 | +import org.onosproject.dhcp.IpAssignment; | ||
25 | + | ||
26 | +import java.util.Date; | ||
27 | + | ||
28 | +import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_Requested; | ||
25 | 29 | ||
26 | /** | 30 | /** |
27 | * Registers a static MAC Address to IP Mapping with the DHCP Server. | 31 | * Registers a static MAC Address to IP Mapping with the DHCP Server. |
... | @@ -49,7 +53,15 @@ public class DhcpSetStaticMapping extends AbstractShellCommand { | ... | @@ -49,7 +53,15 @@ public class DhcpSetStaticMapping extends AbstractShellCommand { |
49 | try { | 53 | try { |
50 | MacAddress macID = MacAddress.valueOf(macAddr); | 54 | MacAddress macID = MacAddress.valueOf(macAddr); |
51 | Ip4Address ipAddress = Ip4Address.valueOf(ipAddr); | 55 | Ip4Address ipAddress = Ip4Address.valueOf(ipAddr); |
52 | - if (dhcpService.setStaticMapping(macID, ipAddress, false, Lists.newArrayList())) { | 56 | + |
57 | + IpAssignment ipAssignment = IpAssignment.builder() | ||
58 | + .ipAddress(ipAddress) | ||
59 | + .leasePeriod(dhcpService.getLeaseTime()) | ||
60 | + .timestamp(new Date()) | ||
61 | + .assignmentStatus(Option_Requested) | ||
62 | + .build(); | ||
63 | + | ||
64 | + if (dhcpService.setStaticMapping(macID, ipAssignment)) { | ||
53 | print(DHCP_SUCCESS); | 65 | print(DHCP_SUCCESS); |
54 | } else { | 66 | } else { |
55 | print(DHCP_FAILURE); | 67 | print(DHCP_FAILURE); | ... | ... |
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
... | @@ -18,7 +18,6 @@ package org.onosproject.dhcp.rest; | ... | @@ -18,7 +18,6 @@ package org.onosproject.dhcp.rest; |
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | import com.fasterxml.jackson.databind.node.ArrayNode; | 19 | import com.fasterxml.jackson.databind.node.ArrayNode; |
20 | import com.fasterxml.jackson.databind.node.ObjectNode; | 20 | import com.fasterxml.jackson.databind.node.ObjectNode; |
21 | -import com.google.common.collect.Lists; | ||
22 | import org.onlab.packet.Ip4Address; | 21 | import org.onlab.packet.Ip4Address; |
23 | import org.onlab.packet.MacAddress; | 22 | import org.onlab.packet.MacAddress; |
24 | import org.onosproject.dhcp.DhcpService; | 23 | import org.onosproject.dhcp.DhcpService; |
... | @@ -36,8 +35,11 @@ import javax.ws.rs.core.MediaType; | ... | @@ -36,8 +35,11 @@ import javax.ws.rs.core.MediaType; |
36 | import javax.ws.rs.core.Response; | 35 | import javax.ws.rs.core.Response; |
37 | import java.io.IOException; | 36 | import java.io.IOException; |
38 | import java.io.InputStream; | 37 | import java.io.InputStream; |
38 | +import java.util.Date; | ||
39 | import java.util.Map; | 39 | import java.util.Map; |
40 | 40 | ||
41 | +import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_Requested; | ||
42 | + | ||
41 | /** | 43 | /** |
42 | * Manage DHCP address assignments. | 44 | * Manage DHCP address assignments. |
43 | */ | 45 | */ |
... | @@ -120,10 +122,15 @@ public class DhcpWebResource extends AbstractWebResource { | ... | @@ -120,10 +122,15 @@ public class DhcpWebResource extends AbstractWebResource { |
120 | JsonNode macID = jsonTree.get("mac"); | 122 | JsonNode macID = jsonTree.get("mac"); |
121 | JsonNode ip = jsonTree.get("ip"); | 123 | JsonNode ip = jsonTree.get("ip"); |
122 | if (macID != null && ip != null) { | 124 | if (macID != null && ip != null) { |
125 | + IpAssignment ipAssignment = IpAssignment.builder() | ||
126 | + .ipAddress(Ip4Address.valueOf(ip.asText())) | ||
127 | + .leasePeriod(service.getLeaseTime()) | ||
128 | + .timestamp(new Date()) | ||
129 | + .assignmentStatus(Option_Requested) | ||
130 | + .build(); | ||
123 | 131 | ||
124 | if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), | 132 | if (!service.setStaticMapping(MacAddress.valueOf(macID.asText()), |
125 | - Ip4Address.valueOf(ip.asText()), | 133 | + ipAssignment)) { |
126 | - false, Lists.newArrayList())) { | ||
127 | throw new IllegalArgumentException("Static Mapping Failed. " + | 134 | throw new IllegalArgumentException("Static Mapping Failed. " + |
128 | "The IP maybe unavailable."); | 135 | "The IP maybe unavailable."); |
129 | } | 136 | } | ... | ... |
... | @@ -28,6 +28,7 @@ import org.onlab.packet.Ip4Address; | ... | @@ -28,6 +28,7 @@ import org.onlab.packet.Ip4Address; |
28 | import org.onlab.packet.IpAddress; | 28 | import org.onlab.packet.IpAddress; |
29 | import org.onlab.packet.MacAddress; | 29 | import org.onlab.packet.MacAddress; |
30 | import org.onlab.packet.UDP; | 30 | import org.onlab.packet.UDP; |
31 | +import org.onosproject.cfg.ComponentConfigAdapter; | ||
31 | import org.onosproject.core.CoreServiceAdapter; | 32 | import org.onosproject.core.CoreServiceAdapter; |
32 | import org.onosproject.dhcp.DhcpStore; | 33 | import org.onosproject.dhcp.DhcpStore; |
33 | import org.onosproject.dhcp.IpAssignment; | 34 | import org.onosproject.dhcp.IpAssignment; |
... | @@ -93,6 +94,7 @@ public class DhcpManagerTest { | ... | @@ -93,6 +94,7 @@ public class DhcpManagerTest { |
93 | hostProviderService = new TestHostProviderService(new TestHostProvider()); | 94 | hostProviderService = new TestHostProviderService(new TestHostProvider()); |
94 | dhcpXManager.hostProviderService = hostProviderService; | 95 | dhcpXManager.hostProviderService = hostProviderService; |
95 | dhcpXManager.hostProviderRegistry = new TestHostRegistry(); | 96 | dhcpXManager.hostProviderRegistry = new TestHostRegistry(); |
97 | + dhcpXManager.componentConfigService = new TestComponentConfig(); | ||
96 | dhcpXManager.activate(); | 98 | dhcpXManager.activate(); |
97 | } | 99 | } |
98 | 100 | ||
... | @@ -228,8 +230,7 @@ public class DhcpManagerTest { | ... | @@ -228,8 +230,7 @@ public class DhcpManagerTest { |
228 | return Ip4Address.valueOf(EXPECTED_IP); | 230 | return Ip4Address.valueOf(EXPECTED_IP); |
229 | } | 231 | } |
230 | 232 | ||
231 | - public boolean assignIP(HostId hostId, Ip4Address ipAddr, int leaseTime, boolean fromOpenStack, | 233 | + public boolean assignIP(HostId hostId, IpAssignment ipAssignment) { |
232 | - List<Ip4Address> addressList) { | ||
233 | return true; | 234 | return true; |
234 | } | 235 | } |
235 | 236 | ||
... | @@ -256,8 +257,7 @@ public class DhcpManagerTest { | ... | @@ -256,8 +257,7 @@ public class DhcpManagerTest { |
256 | return map; | 257 | return map; |
257 | } | 258 | } |
258 | 259 | ||
259 | - public boolean assignStaticIP(MacAddress macID, Ip4Address ipAddr, boolean fromOpenStack, | 260 | + public boolean assignStaticIP(MacAddress macID, IpAssignment ipAssignment) { |
260 | - List<Ip4Address> addressList) { | ||
261 | return true; | 261 | return true; |
262 | } | 262 | } |
263 | 263 | ||
... | @@ -327,6 +327,13 @@ public class DhcpManagerTest { | ... | @@ -327,6 +327,13 @@ public class DhcpManagerTest { |
327 | } | 327 | } |
328 | 328 | ||
329 | /** | 329 | /** |
330 | + * Mocks the ComponentConfigRegistry. | ||
331 | + */ | ||
332 | + private class TestComponentConfig extends ComponentConfigAdapter { | ||
333 | + | ||
334 | + } | ||
335 | + | ||
336 | + /** | ||
330 | * Mocks the HostProviderService. | 337 | * Mocks the HostProviderService. |
331 | */ | 338 | */ |
332 | private class TestHostProviderService extends AbstractProviderService<HostProvider> | 339 | private class TestHostProviderService extends AbstractProviderService<HostProvider> | ... | ... |
... | @@ -9,14 +9,14 @@ | ... | @@ -9,14 +9,14 @@ |
9 | "router": "10.0.0.1", | 9 | "router": "10.0.0.1", |
10 | "domain": "10.0.0.1", | 10 | "domain": "10.0.0.1", |
11 | "ttl": "63", | 11 | "ttl": "63", |
12 | - "lease": "300", | 12 | + "lease": 300, |
13 | "renew": "150", | 13 | "renew": "150", |
14 | - "rebind": "200", | 14 | + "rebind": 200, |
15 | "delay": "3", | 15 | "delay": "3", |
16 | - "timeout": "150", | 16 | + "timeout": 150, |
17 | "startip": "10.0.0.110", | 17 | "startip": "10.0.0.110", |
18 | "endip": "10.0.0.130" | 18 | "endip": "10.0.0.130" |
19 | } | 19 | } |
20 | } | 20 | } |
21 | } | 21 | } |
22 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
22 | +} | ... | ... |
... | @@ -15,7 +15,6 @@ | ... | @@ -15,7 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.openstacknetworking.switching; | 16 | package org.onosproject.openstacknetworking.switching; |
17 | 17 | ||
18 | -import com.google.common.collect.ImmutableList; | ||
19 | import com.google.common.collect.ImmutableMap; | 18 | import com.google.common.collect.ImmutableMap; |
20 | import com.google.common.collect.Maps; | 19 | import com.google.common.collect.Maps; |
21 | import org.apache.felix.scr.annotations.Activate; | 20 | import org.apache.felix.scr.annotations.Activate; |
... | @@ -26,9 +25,11 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; | ... | @@ -26,9 +25,11 @@ import org.apache.felix.scr.annotations.ReferenceCardinality; |
26 | import org.apache.felix.scr.annotations.Service; | 25 | import org.apache.felix.scr.annotations.Service; |
27 | import org.onlab.packet.Ethernet; | 26 | import org.onlab.packet.Ethernet; |
28 | import org.onlab.packet.Ip4Address; | 27 | import org.onlab.packet.Ip4Address; |
28 | +import org.onlab.packet.IpPrefix; | ||
29 | import org.onosproject.core.ApplicationId; | 29 | import org.onosproject.core.ApplicationId; |
30 | import org.onosproject.core.CoreService; | 30 | import org.onosproject.core.CoreService; |
31 | import org.onosproject.dhcp.DhcpService; | 31 | import org.onosproject.dhcp.DhcpService; |
32 | +import org.onosproject.dhcp.IpAssignment; | ||
32 | import org.onosproject.event.AbstractEvent; | 33 | import org.onosproject.event.AbstractEvent; |
33 | import org.onosproject.net.Device; | 34 | import org.onosproject.net.Device; |
34 | import org.onosproject.net.DeviceId; | 35 | import org.onosproject.net.DeviceId; |
... | @@ -61,13 +62,18 @@ import org.onosproject.openstacknetworking.OpenstackNetworkingConfig; | ... | @@ -61,13 +62,18 @@ import org.onosproject.openstacknetworking.OpenstackNetworkingConfig; |
61 | import org.onosproject.openstacknetworking.OpenstackSwitchingService; | 62 | import org.onosproject.openstacknetworking.OpenstackSwitchingService; |
62 | import org.slf4j.Logger; | 63 | import org.slf4j.Logger; |
63 | import org.slf4j.LoggerFactory; | 64 | import org.slf4j.LoggerFactory; |
64 | -import java.util.List; | 65 | + |
66 | +import java.util.Date; | ||
65 | import java.util.Collection; | 67 | import java.util.Collection; |
66 | import java.util.Map; | 68 | import java.util.Map; |
67 | import java.util.concurrent.ExecutorService; | 69 | import java.util.concurrent.ExecutorService; |
68 | import java.util.concurrent.Executors; | 70 | import java.util.concurrent.Executors; |
69 | 71 | ||
70 | import static org.onlab.util.Tools.groupedThreads; | 72 | import static org.onlab.util.Tools.groupedThreads; |
73 | +import static org.onosproject.dhcp.IpAssignment.AssignmentStatus.Option_RangeNotEnforced; | ||
74 | + | ||
75 | +import static com.google.common.base.Preconditions.checkArgument; | ||
76 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
71 | 77 | ||
72 | @Service | 78 | @Service |
73 | @Component(immediate = true) | 79 | @Component(immediate = true) |
... | @@ -117,8 +123,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -117,8 +123,9 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
117 | public static final String PORTNAME = "portName"; | 123 | public static final String PORTNAME = "portName"; |
118 | private static final String ROUTER_INTERFACE = "network:router_interface"; | 124 | private static final String ROUTER_INTERFACE = "network:router_interface"; |
119 | public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway"; | 125 | public static final String DEVICE_OWNER_GATEWAY = "network:router_gateway"; |
120 | - public static final String DNS_SERVER_IP = "8.8.8.8"; | 126 | + public static final Ip4Address DNS_SERVER_IP = Ip4Address.valueOf("8.8.8.8"); |
121 | private static final String FORWARD_SLASH = "/"; | 127 | private static final String FORWARD_SLASH = "/"; |
128 | + private static final int DHCP_INFINITE_LEASE = -1; | ||
122 | 129 | ||
123 | 130 | ||
124 | private ApplicationId appId; | 131 | private ApplicationId appId; |
... | @@ -372,42 +379,41 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { | ... | @@ -372,42 +379,41 @@ public class OpenstackSwitchingManager implements OpenstackSwitchingService { |
372 | } | 379 | } |
373 | 380 | ||
374 | private void registerDhcpInfo(OpenstackPort openstackPort) { | 381 | private void registerDhcpInfo(OpenstackPort openstackPort) { |
375 | - Ip4Address ip4Address, subnetMask, gatewayIPAddress, dhcpServer, domainServer; | 382 | + checkNotNull(openstackPort); |
376 | - OpenstackSubnet openstackSubnet; | 383 | + checkArgument(!openstackPort.fixedIps().isEmpty()); |
377 | 384 | ||
378 | - ip4Address = (Ip4Address) openstackPort.fixedIps().values().stream().findFirst().orElse(null); | 385 | + OpenstackSubnet openstackSubnet = openstackService.subnets().stream() |
379 | - | ||
380 | - openstackSubnet = openstackService.subnets().stream() | ||
381 | .filter(n -> n.networkId().equals(openstackPort.networkId())) | 386 | .filter(n -> n.networkId().equals(openstackPort.networkId())) |
382 | - .findFirst().get(); | 387 | + .findFirst().orElse(null); |
383 | - | 388 | + if (openstackSubnet == null) { |
384 | - subnetMask = Ip4Address.valueOf(buildSubnetMask(openstackSubnet.cidr())); | 389 | + log.warn("Failed to find subnet for {}", openstackPort); |
385 | - gatewayIPAddress = Ip4Address.valueOf(openstackSubnet.gatewayIp()); | 390 | + return; |
386 | - dhcpServer = gatewayIPAddress; | ||
387 | - // TODO: supports multiple DNS servers | ||
388 | - if (openstackSubnet.dnsNameservers().isEmpty()) { | ||
389 | - domainServer = Ip4Address.valueOf(DNS_SERVER_IP); | ||
390 | - } else { | ||
391 | - domainServer = openstackSubnet.dnsNameservers().get(0); | ||
392 | } | 391 | } |
393 | - List<Ip4Address> options = ImmutableList.of(subnetMask, dhcpServer, gatewayIPAddress, domainServer); | ||
394 | - | ||
395 | - dhcpService.setStaticMapping(openstackPort.macAddress(), ip4Address, true, options); | ||
396 | - } | ||
397 | 392 | ||
398 | - private byte[] buildSubnetMask(String cidr) { | 393 | + Ip4Address ipAddress = openstackPort.fixedIps().values().stream().findFirst().get(); |
399 | - int prefix; | 394 | + IpPrefix subnetPrefix = IpPrefix.valueOf(openstackSubnet.cidr()); |
400 | - String[] parts = cidr.split(FORWARD_SLASH); | 395 | + Ip4Address broadcast = Ip4Address.makeMaskedAddress( |
401 | - prefix = Integer.parseInt(parts[1]); | 396 | + ipAddress, |
402 | - int mask = 0xffffffff << (32 - prefix); | 397 | + subnetPrefix.prefixLength()); |
403 | - byte[] bytes = new byte[]{(byte) (mask >>> 24), | ||
404 | - (byte) (mask >> 16 & 0xff), (byte) (mask >> 8 & 0xff), (byte) (mask & 0xff)}; | ||
405 | 398 | ||
406 | - return bytes; | 399 | + // TODO: supports multiple DNS servers |
400 | + Ip4Address domainServer = openstackSubnet.dnsNameservers().isEmpty() ? | ||
401 | + DNS_SERVER_IP : openstackSubnet.dnsNameservers().get(0); | ||
402 | + | ||
403 | + IpAssignment ipAssignment = IpAssignment.builder() | ||
404 | + .ipAddress(ipAddress) | ||
405 | + .leasePeriod(DHCP_INFINITE_LEASE) | ||
406 | + .timestamp(new Date()) | ||
407 | + .subnetMask(Ip4Address.makeMaskPrefix(subnetPrefix.prefixLength())) | ||
408 | + .broadcast(broadcast) | ||
409 | + .domainServer(domainServer) | ||
410 | + .assignmentStatus(Option_RangeNotEnforced) | ||
411 | + .routerAddress(Ip4Address.valueOf(openstackSubnet.gatewayIp())) | ||
412 | + .build(); | ||
413 | + | ||
414 | + dhcpService.setStaticMapping(openstackPort.macAddress(), ipAssignment); | ||
407 | } | 415 | } |
408 | 416 | ||
409 | - | ||
410 | - | ||
411 | private class InternalPacketProcessor implements PacketProcessor { | 417 | private class InternalPacketProcessor implements PacketProcessor { |
412 | 418 | ||
413 | @Override | 419 | @Override | ... | ... |
-
Please register or login to post a comment