Kyuhwi Choi
Committed by Gerrit Code Review

[ONOS-3952] Implement FloatingIP Handler for OpenstackRoutingService

 - Implements floatingIp REST interfaces & event handler
 - Implements rulePopulate method for floatingIp handler
 - Fixes minor logics
 - Changes app structure
 - exports configuration
 - Implements case issue.
   when openstack deletes vm w/o deassociating floatingIp,
   openstack doesn`t send floatingIp deassociation event.

Change-Id: If4d8ac3fecfed1957d84139f94ae31f593a9097b
...@@ -80,5 +80,11 @@ public interface OpenstackRoutingService { ...@@ -80,5 +80,11 @@ public interface OpenstackRoutingService {
80 */ 80 */
81 void removeRouterInterface(OpenstackRouterInterface openstackRouterInterface); 81 void removeRouterInterface(OpenstackRouterInterface openstackRouterInterface);
82 82
83 - 83 + /**
84 + * Checks floatingIp deassociation when corresponding deleted vm.
85 + *
86 + * @param portId Deleted vm
87 + * @param portInfo
88 + */
89 + void checkDisassociatedFloatingIp(String portId, OpenstackPortInfo portInfo);
84 } 90 }
......
...@@ -15,20 +15,34 @@ ...@@ -15,20 +15,34 @@
15 */ 15 */
16 package org.onosproject.openstacknetworking.routing; 16 package org.onosproject.openstacknetworking.routing;
17 17
18 - import org.onosproject.event.AbstractEvent; 18 +import org.onosproject.openstackinterface.OpenstackFloatingIP;
19 +import org.onosproject.openstacknetworking.OpenstackPortInfo;
19 20
20 /** 21 /**
21 * Handle FloatingIP Event for Managing Flow Rules In Openstack Nodes. 22 * Handle FloatingIP Event for Managing Flow Rules In Openstack Nodes.
22 */ 23 */
23 public class OpenstackFloatingIPHandler implements Runnable { 24 public class OpenstackFloatingIPHandler implements Runnable {
24 25
25 - volatile AbstractEvent event; 26 + private final OpenstackFloatingIP floatingIP;
26 - OpenstackFloatingIPHandler(AbstractEvent event) { 27 + private final OpenstackRoutingRulePopulator rulePopulator;
27 - this.event = event; 28 + private boolean associate;
29 + private final OpenstackPortInfo portInfo;
30 +
31 + OpenstackFloatingIPHandler(OpenstackRoutingRulePopulator rulePopulator,
32 + OpenstackFloatingIP openstackFloatingIP, boolean associate, OpenstackPortInfo portInfo) {
33 + this.floatingIP = openstackFloatingIP;
34 + this.rulePopulator = rulePopulator;
35 + this.associate = associate;
36 + this.portInfo = portInfo;
28 } 37 }
29 38
30 @Override 39 @Override
31 public void run() { 40 public void run() {
41 + if (associate) {
42 + rulePopulator.populateFloatingIpRules(floatingIP);
43 + } else {
44 + rulePopulator.removeFloatingIpRules(floatingIP, portInfo);
45 + }
32 46
33 } 47 }
34 } 48 }
......
...@@ -56,19 +56,18 @@ public class OpenstackPnatHandler implements Runnable { ...@@ -56,19 +56,18 @@ public class OpenstackPnatHandler implements Runnable {
56 private final int portNum; 56 private final int portNum;
57 private final OpenstackPort openstackPort; 57 private final OpenstackPort openstackPort;
58 private final Port port; 58 private final Port port;
59 + private OpenstackRoutingConfig config;
59 60
60 private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface"; 61 private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface";
61 - // TODO: This will be replaced to get the information from openstacknetworkingservice.
62 - private static final MacAddress GATEWAYMAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
63 - private static final MacAddress EXTERNAL_INTERFACE_MAC = MacAddress.valueOf("00:00:00:00:00:11");
64 62
65 OpenstackPnatHandler(OpenstackRoutingRulePopulator rulePopulator, PacketContext context, 63 OpenstackPnatHandler(OpenstackRoutingRulePopulator rulePopulator, PacketContext context,
66 - int portNum, OpenstackPort openstackPort, Port port) { 64 + int portNum, OpenstackPort openstackPort, Port port, OpenstackRoutingConfig config) {
67 this.rulePopulator = checkNotNull(rulePopulator); 65 this.rulePopulator = checkNotNull(rulePopulator);
68 this.context = checkNotNull(context); 66 this.context = checkNotNull(context);
69 this.portNum = checkNotNull(portNum); 67 this.portNum = checkNotNull(portNum);
70 this.openstackPort = checkNotNull(openstackPort); 68 this.openstackPort = checkNotNull(openstackPort);
71 this.port = checkNotNull(port); 69 this.port = checkNotNull(port);
70 + this.config = checkNotNull(config);
72 } 71 }
73 72
74 @Override 73 @Override
...@@ -85,7 +84,8 @@ public class OpenstackPnatHandler implements Runnable { ...@@ -85,7 +84,8 @@ public class OpenstackPnatHandler implements Runnable {
85 OpenstackRouter router = getOpenstackRouter(openstackPort); 84 OpenstackRouter router = getOpenstackRouter(openstackPort);
86 85
87 rulePopulator.populatePnatFlowRules(inboundPacket, openstackPort, portNum, 86 rulePopulator.populatePnatFlowRules(inboundPacket, openstackPort, portNum,
88 - getExternalIp(router), getExternalInterfaceMacAddress(), getExternalRouterMacAddress()); 87 + getExternalIp(router), MacAddress.valueOf(config.gatewayExternalInterfaceMac()),
88 + MacAddress.valueOf(config.physicalRouterMac()));
89 89
90 packetOut((Ethernet) ethernet.clone(), inboundPacket.receivedFrom().deviceId(), portNum, router); 90 packetOut((Ethernet) ethernet.clone(), inboundPacket.receivedFrom().deviceId(), portNum, router);
91 } 91 }
...@@ -144,8 +144,9 @@ public class OpenstackPnatHandler implements Runnable { ...@@ -144,8 +144,9 @@ public class OpenstackPnatHandler implements Runnable {
144 iPacket.setSourceAddress(getExternalIp(router).toString()); 144 iPacket.setSourceAddress(getExternalIp(router).toString());
145 iPacket.resetChecksum(); 145 iPacket.resetChecksum();
146 iPacket.setParent(ethernet); 146 iPacket.setParent(ethernet);
147 - ethernet.setSourceMACAddress(getExternalInterfaceMacAddress()) 147 + ethernet.setPayload(iPacket);
148 - .setDestinationMACAddress(getExternalRouterMacAddress()); 148 + ethernet.setSourceMACAddress(config.gatewayExternalInterfaceMac())
149 + .setDestinationMACAddress(config.physicalRouterMac());
149 ethernet.resetChecksum(); 150 ethernet.resetChecksum();
150 151
151 treatment.setOutput(port.number()); 152 treatment.setOutput(port.number());
...@@ -153,11 +154,4 @@ public class OpenstackPnatHandler implements Runnable { ...@@ -153,11 +154,4 @@ public class OpenstackPnatHandler implements Runnable {
153 packetService.emit(new DefaultOutboundPacket(deviceId, treatment.build(), 154 packetService.emit(new DefaultOutboundPacket(deviceId, treatment.build(),
154 ByteBuffer.wrap(ethernet.serialize()))); 155 ByteBuffer.wrap(ethernet.serialize())));
155 } 156 }
156 -
157 - private MacAddress getExternalInterfaceMacAddress() {
158 - return EXTERNAL_INTERFACE_MAC;
159 - }
160 - private MacAddress getExternalRouterMacAddress() {
161 - return GATEWAYMAC;
162 - }
163 } 157 }
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
16 package org.onosproject.openstacknetworking.routing; 16 package org.onosproject.openstacknetworking.routing;
17 17
18 import com.google.common.collect.Lists; 18 import com.google.common.collect.Lists;
19 -import com.google.common.collect.Maps;
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;
22 import org.apache.felix.scr.annotations.Deactivate; 21 import org.apache.felix.scr.annotations.Deactivate;
...@@ -28,6 +27,7 @@ import org.onlab.packet.IPv4; ...@@ -28,6 +27,7 @@ import org.onlab.packet.IPv4;
28 import org.onlab.packet.Ip4Address; 27 import org.onlab.packet.Ip4Address;
29 import org.onlab.packet.MacAddress; 28 import org.onlab.packet.MacAddress;
30 import org.onlab.packet.UDP; 29 import org.onlab.packet.UDP;
30 +import org.onlab.util.KryoNamespace;
31 import org.onosproject.core.ApplicationId; 31 import org.onosproject.core.ApplicationId;
32 import org.onosproject.core.CoreService; 32 import org.onosproject.core.CoreService;
33 import org.onosproject.net.DeviceId; 33 import org.onosproject.net.DeviceId;
...@@ -50,14 +50,18 @@ import org.onosproject.openstackinterface.OpenstackInterfaceService; ...@@ -50,14 +50,18 @@ import org.onosproject.openstackinterface.OpenstackInterfaceService;
50 import org.onosproject.openstackinterface.OpenstackPort; 50 import org.onosproject.openstackinterface.OpenstackPort;
51 import org.onosproject.openstackinterface.OpenstackRouter; 51 import org.onosproject.openstackinterface.OpenstackRouter;
52 import org.onosproject.openstackinterface.OpenstackRouterInterface; 52 import org.onosproject.openstackinterface.OpenstackRouterInterface;
53 +import org.onosproject.openstacknetworking.OpenstackPortInfo;
53 import org.onosproject.openstacknetworking.OpenstackRoutingService; 54 import org.onosproject.openstacknetworking.OpenstackRoutingService;
54 import org.onosproject.openstacknetworking.OpenstackSwitchingService; 55 import org.onosproject.openstacknetworking.OpenstackSwitchingService;
56 +import org.onosproject.store.serializers.KryoNamespaces;
57 +import org.onosproject.store.service.ConsistentMap;
58 +import org.onosproject.store.service.Serializer;
59 +import org.onosproject.store.service.StorageService;
55 import org.slf4j.Logger; 60 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory; 61 import org.slf4j.LoggerFactory;
57 62
58 import java.util.Collection; 63 import java.util.Collection;
59 import java.util.List; 64 import java.util.List;
60 -import java.util.Map;
61 import java.util.concurrent.ExecutorService; 65 import java.util.concurrent.ExecutorService;
62 import java.util.concurrent.Executors; 66 import java.util.concurrent.Executors;
63 import java.util.stream.Collectors; 67 import java.util.stream.Collectors;
...@@ -101,14 +105,21 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -101,14 +105,21 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
101 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
102 protected NetworkConfigRegistry configRegistry; 106 protected NetworkConfigRegistry configRegistry;
103 107
104 - 108 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 + protected StorageService storageService;
105 110
106 private ApplicationId appId; 111 private ApplicationId appId;
107 - private Map<String, OpenstackRouterInterface> routerInterfaceMap = Maps.newHashMap(); 112 + private ConsistentMap<Integer, String> tpPortNumMap; // Map<PortNum, allocated VM`s Mac & destionation Ip address>
108 - private Map<Integer, String> portNumMap = initPortNumMap(); 113 + private ConsistentMap<String, OpenstackFloatingIP> floatingIpMap; // Map<FloatingIp`s Id, FloatingIp object>
109 private static final String APP_ID = "org.onosproject.openstackrouting"; 114 private static final String APP_ID = "org.onosproject.openstackrouting";
110 private static final String PORT_NAME = "portName"; 115 private static final String PORT_NAME = "portName";
116 + private static final String PORTNAME_PREFIX_VM = "tap";
111 private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface"; 117 private static final String DEVICE_OWNER_ROUTER_INTERFACE = "network:router_interface";
118 + private static final String FLOATING_IP_MAP_NAME = "openstackrouting-floatingip";
119 + private static final String TP_PORT_MAP_NAME = "openstackrouting-portnum";
120 + private static final int PNAT_PORT_EXPIRE_TIME = 1200 * 1000;
121 + private static final int TP_PORT_MINIMUM_NUM = 1024;
122 + private static final int TP_PORT_MAXIMUM_NUM = 65535;
112 private final ConfigFactory configFactory = 123 private final ConfigFactory configFactory =
113 new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, OpenstackRoutingConfig.class, "openstackrouting") { 124 new ConfigFactory(SubjectFactories.APP_SUBJECT_FACTORY, OpenstackRoutingConfig.class, "openstackrouting") {
114 @Override 125 @Override
...@@ -119,16 +130,19 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -119,16 +130,19 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
119 private final NetworkConfigListener configListener = new InternalConfigListener(); 130 private final NetworkConfigListener configListener = new InternalConfigListener();
120 131
121 private OpenstackRoutingConfig config; 132 private OpenstackRoutingConfig config;
122 - private static final int PNAT_PORT_NUM_START = 1024; 133 + private static final KryoNamespace.Builder FLOATING_IP_SERIALIZER = KryoNamespace.newBuilder()
123 - private static final int PNAT_PORT_NUM_END = 65535; 134 + .register(KryoNamespaces.API)
124 - 135 + .register(KryoNamespaces.MISC)
125 - private Map<Integer, String> initPortNumMap() { 136 + .register(OpenstackFloatingIP.FloatingIpStatus.class)
126 - Map<Integer, String> map = Maps.newHashMap(); 137 + .register(OpenstackFloatingIP.class)
127 - for (int i = PNAT_PORT_NUM_START; i < PNAT_PORT_NUM_END; i++) { 138 + .register(Ip4Address.class)
128 - map.put(i, ""); 139 + .register(String.class);
129 - } 140 +
130 - return map; 141 + private static final KryoNamespace.Builder NUMBER_SERIALIZER = KryoNamespace.newBuilder()
131 - } 142 + .register(KryoNamespaces.API)
143 + .register(KryoNamespaces.MISC)
144 + .register(Integer.class)
145 + .register(String.class);
132 146
133 private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor(); 147 private InternalPacketProcessor internalPacketProcessor = new InternalPacketProcessor();
134 private ExecutorService l3EventExecutorService = 148 private ExecutorService l3EventExecutorService =
...@@ -139,6 +153,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -139,6 +153,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
139 Executors.newSingleThreadExecutor(groupedThreads("onos/openstackrouting", "arp-event")); 153 Executors.newSingleThreadExecutor(groupedThreads("onos/openstackrouting", "arp-event"));
140 private OpenstackIcmpHandler openstackIcmpHandler; 154 private OpenstackIcmpHandler openstackIcmpHandler;
141 private OpenstackRoutingArpHandler openstackArpHandler; 155 private OpenstackRoutingArpHandler openstackArpHandler;
156 + private OpenstackRoutingRulePopulator rulePopulator;
142 157
143 @Activate 158 @Activate
144 protected void activate() { 159 protected void activate() {
...@@ -149,6 +164,17 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -149,6 +164,17 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
149 164
150 readConfiguration(); 165 readConfiguration();
151 166
167 + floatingIpMap = storageService.<String, OpenstackFloatingIP>consistentMapBuilder()
168 + .withSerializer(Serializer.using(FLOATING_IP_SERIALIZER.build()))
169 + .withName(FLOATING_IP_MAP_NAME)
170 + .withApplicationId(appId)
171 + .build();
172 + tpPortNumMap = storageService.<Integer, String>consistentMapBuilder()
173 + .withSerializer(Serializer.using(NUMBER_SERIALIZER.build()))
174 + .withName(TP_PORT_MAP_NAME)
175 + .withApplicationId(appId)
176 + .build();
177 +
152 log.info("onos-openstackrouting started"); 178 log.info("onos-openstackrouting started");
153 } 179 }
154 180
...@@ -159,43 +185,92 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -159,43 +185,92 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
159 icmpEventExecutorService.shutdown(); 185 icmpEventExecutorService.shutdown();
160 arpEventExecutorService.shutdown(); 186 arpEventExecutorService.shutdown();
161 187
188 + floatingIpMap.clear();
189 + tpPortNumMap.clear();
190 +
162 log.info("onos-openstackrouting stopped"); 191 log.info("onos-openstackrouting stopped");
163 } 192 }
164 193
165 194
166 @Override 195 @Override
167 public void createFloatingIP(OpenstackFloatingIP openstackFloatingIP) { 196 public void createFloatingIP(OpenstackFloatingIP openstackFloatingIP) {
168 - 197 + floatingIpMap.put(openstackFloatingIP.id(), openstackFloatingIP);
169 } 198 }
170 199
171 @Override 200 @Override
172 public void updateFloatingIP(OpenstackFloatingIP openstackFloatingIP) { 201 public void updateFloatingIP(OpenstackFloatingIP openstackFloatingIP) {
173 - 202 + if (!floatingIpMap.containsKey(openstackFloatingIP.id())) {
203 + log.warn("There`s no information about {} in FloatingIpMap", openstackFloatingIP.id());
204 + return;
205 + }
206 + if (openstackFloatingIP.portId() == null || openstackFloatingIP.portId().equals("null")) {
207 + OpenstackFloatingIP floatingIP = floatingIpMap.get(openstackFloatingIP.id()).value();
208 + OpenstackPortInfo portInfo = openstackSwitchingService.openstackPortInfo()
209 + .get(PORTNAME_PREFIX_VM.concat(floatingIP.portId().substring(0, 11)));
210 + if (portInfo == null) {
211 + log.warn("There`s no portInfo information about portId {}", floatingIP.portId());
212 + return;
213 + }
214 + l3EventExecutorService.execute(
215 + new OpenstackFloatingIPHandler(rulePopulator, floatingIP, false, portInfo));
216 + floatingIpMap.replace(floatingIP.id(), openstackFloatingIP);
217 + } else {
218 + floatingIpMap.put(openstackFloatingIP.id(), openstackFloatingIP);
219 + l3EventExecutorService.execute(
220 + new OpenstackFloatingIPHandler(rulePopulator, openstackFloatingIP, true, null));
221 + }
174 } 222 }
175 223
176 @Override 224 @Override
177 public void deleteFloatingIP(String id) { 225 public void deleteFloatingIP(String id) {
178 - 226 + floatingIpMap.remove(id);
179 } 227 }
180 228
181 @Override 229 @Override
182 public void createRouter(OpenstackRouter openstackRouter) { 230 public void createRouter(OpenstackRouter openstackRouter) {
183 - checkExternalConnection(openstackRouter, getOpenstackRouterInterface(openstackRouter));
184 } 231 }
185 232
186 @Override 233 @Override
187 public void updateRouter(OpenstackRouter openstackRouter) { 234 public void updateRouter(OpenstackRouter openstackRouter) {
188 - checkExternalConnection(openstackRouter, getOpenstackRouterInterface(openstackRouter)); 235 + if (openstackRouter.gatewayExternalInfo().externalFixedIps().size() > 0) {
236 + Ip4Address externalIp = openstackRouter.gatewayExternalInfo().externalFixedIps()
237 + .values().stream().findFirst().orElse(null);
238 + OpenstackRouter router = getRouterfromExternalIp(externalIp);
239 + checkExternalConnection(router, getOpenstackRouterInterface(router));
240 + } else {
241 + unsetExternalConnection();
242 + }
243 + }
244 +
245 + private void unsetExternalConnection() {
246 + Collection<OpenstackRouter> internalRouters = getExternalRouter(false);
247 + internalRouters.forEach(r ->
248 + getOpenstackRouterInterface(r).forEach(i -> rulePopulator.removeExternalRules(i)));
249 + }
250 +
251 + private Collection<OpenstackRouter> getExternalRouter(boolean externalConnection) {
252 + List<OpenstackRouter> routers;
253 + if (externalConnection) {
254 + routers = openstackService.routers()
255 + .stream()
256 + .filter(r -> (r.gatewayExternalInfo().externalFixedIps().size() > 0))
257 + .collect(Collectors.toList());
258 + } else {
259 + routers = openstackService.routers()
260 + .stream()
261 + .filter(r -> (r.gatewayExternalInfo().externalFixedIps().size() == 0))
262 + .collect(Collectors.toList());
263 + }
264 + return routers;
189 } 265 }
190 266
191 @Override 267 @Override
192 public void deleteRouter(String id) { 268 public void deleteRouter(String id) {
193 - //TODO 269 + //TODO : In now, there`s nothing to do for deleteRouter process. It is reserved.
194 } 270 }
195 271
196 @Override 272 @Override
197 public void updateRouterInterface(OpenstackRouterInterface routerInterface) { 273 public void updateRouterInterface(OpenstackRouterInterface routerInterface) {
198 - routerInterfaceMap.putIfAbsent(routerInterface.id(), routerInterface);
199 List<OpenstackRouterInterface> routerInterfaces = Lists.newArrayList(); 274 List<OpenstackRouterInterface> routerInterfaces = Lists.newArrayList();
200 routerInterfaces.add(routerInterface); 275 routerInterfaces.add(routerInterface);
201 checkExternalConnection(getOpenstackRouter(routerInterface.id()), routerInterfaces); 276 checkExternalConnection(getOpenstackRouter(routerInterface.id()), routerInterfaces);
...@@ -203,20 +278,55 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -203,20 +278,55 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
203 278
204 @Override 279 @Override
205 public void removeRouterInterface(OpenstackRouterInterface routerInterface) { 280 public void removeRouterInterface(OpenstackRouterInterface routerInterface) {
206 - OpenstackRoutingRulePopulator rulePopulator = new OpenstackRoutingRulePopulator(appId,
207 - openstackService, flowObjectiveService, deviceService, driverService, config);
208 rulePopulator.removeExternalRules(routerInterface); 281 rulePopulator.removeExternalRules(routerInterface);
209 - routerInterfaceMap.remove(routerInterface.portId()); 282 + }
283 +
284 + @Override
285 + public void checkDisassociatedFloatingIp(String portId, OpenstackPortInfo portInfo) {
286 + if (floatingIpMap.size() < 1) {
287 + log.info("No information in FloatingIpMap");
288 + return;
289 + }
290 + OpenstackFloatingIP floatingIp = associatedFloatingIps()
291 + .stream()
292 + .filter(fIp -> fIp.portId().equals(portId))
293 + .findAny()
294 + .orElse(null);
295 + if (floatingIp != null && portInfo != null) {
296 + l3EventExecutorService.execute(
297 + new OpenstackFloatingIPHandler(rulePopulator, floatingIp, false, portInfo));
298 + OpenstackFloatingIP.Builder fBuilder = new OpenstackFloatingIP.Builder()
299 + .floatingIpAddress(floatingIp.floatingIpAddress())
300 + .id(floatingIp.id())
301 + .networkId(floatingIp.networkId())
302 + .status(floatingIp.status())
303 + .tenantId(floatingIp.tenantId());
304 + floatingIpMap.replace(floatingIp.id(), fBuilder.build());
305 + } else if (portInfo == null) {
306 + log.warn("portInfo is null as timing issue between ovs port update event and openstack deletePort event");
307 + }
308 + }
309 +
310 + private Collection<OpenstackFloatingIP> associatedFloatingIps() {
311 + List<OpenstackFloatingIP> fIps = Lists.newArrayList();
312 + floatingIpMap.values()
313 + .stream()
314 + .filter(fIp -> fIp.value().portId() != null)
315 + .forEach(fIp -> fIps.add(fIp.value()));
316 + return fIps;
210 } 317 }
211 318
212 private void reloadInitL3Rules() { 319 private void reloadInitL3Rules() {
320 + l3EventExecutorService.submit(() ->
213 openstackService.ports() 321 openstackService.ports()
214 .stream() 322 .stream()
215 .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE)) 323 .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
216 .forEach(p -> { 324 .forEach(p -> {
217 OpenstackRouterInterface routerInterface = portToRouterInterface(p); 325 OpenstackRouterInterface routerInterface = portToRouterInterface(p);
218 updateRouterInterface(routerInterface); 326 updateRouterInterface(routerInterface);
219 - }); 327 + })
328 + );
329 +
220 } 330 }
221 331
222 private OpenstackRouterInterface portToRouterInterface(OpenstackPort p) { 332 private OpenstackRouterInterface portToRouterInterface(OpenstackPort p) {
...@@ -249,8 +359,6 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -249,8 +359,6 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
249 return; 359 return;
250 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) { 360 } else if (ethernet.getEtherType() == Ethernet.TYPE_IPV4) {
251 IPv4 iPacket = (IPv4) ethernet.getPayload(); 361 IPv4 iPacket = (IPv4) ethernet.getPayload();
252 - OpenstackRoutingRulePopulator rulePopulator = new OpenstackRoutingRulePopulator(appId,
253 - openstackService, flowObjectiveService, deviceService, driverService, config);
254 switch (iPacket.getProtocol()) { 362 switch (iPacket.getProtocol()) {
255 case IPv4.PROTOCOL_ICMP: 363 case IPv4.PROTOCOL_ICMP:
256 364
...@@ -275,7 +383,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -275,7 +383,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
275 OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(), 383 OpenstackPort openstackPort = getOpenstackPort(ethernet.getSourceMAC(),
276 Ip4Address.valueOf(iPacket.getSourceAddress())); 384 Ip4Address.valueOf(iPacket.getSourceAddress()));
277 l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context, 385 l3EventExecutorService.execute(new OpenstackPnatHandler(rulePopulator, context,
278 - portNum, openstackPort, port)); 386 + portNum, openstackPort, port, config));
279 break; 387 break;
280 } 388 }
281 } else if (ethernet.getEtherType() == Ethernet.TYPE_ARP) { 389 } else if (ethernet.getEtherType() == Ethernet.TYPE_ARP) {
...@@ -285,11 +393,32 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -285,11 +393,32 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
285 } 393 }
286 394
287 private int getPortNum(MacAddress sourceMac, int destinationAddress) { 395 private int getPortNum(MacAddress sourceMac, int destinationAddress) {
288 - int portNum = portNumMap.keySet().stream() 396 + int portNum = findUnusedPortNum();
289 - .filter(k -> portNumMap.get(k).equals("")).findFirst().orElse(0); 397 + if (portNum == 0) {
290 - portNumMap.replace(portNum, sourceMac.toString().concat(":").concat(String.valueOf(destinationAddress))); 398 + clearPortNumMap();
399 + portNum = findUnusedPortNum();
400 + }
401 + tpPortNumMap.put(portNum, sourceMac.toString().concat(":").concat(String.valueOf(destinationAddress)));
291 return portNum; 402 return portNum;
292 } 403 }
404 +
405 + private int findUnusedPortNum() {
406 + for (int i = TP_PORT_MINIMUM_NUM; i < TP_PORT_MAXIMUM_NUM; i++) {
407 + if (!tpPortNumMap.containsKey(i)) {
408 + return i;
409 + }
410 + }
411 + return 0;
412 + }
413 +
414 + }
415 +
416 + private void clearPortNumMap() {
417 + tpPortNumMap.entrySet().forEach(e -> {
418 + if (System.currentTimeMillis() - e.getValue().creationTime() > PNAT_PORT_EXPIRE_TIME) {
419 + tpPortNumMap.remove(e.getKey());
420 + }
421 + });
293 } 422 }
294 423
295 private Port getExternalPort(DeviceId deviceId, String interfaceName) { 424 private Port getExternalPort(DeviceId deviceId, String interfaceName) {
...@@ -301,29 +430,55 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -301,29 +430,55 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
301 } 430 }
302 431
303 private void checkExternalConnection(OpenstackRouter router, 432 private void checkExternalConnection(OpenstackRouter router,
304 - Collection<OpenstackRouterInterface> routerInterfaces) { 433 + Collection<OpenstackRouterInterface> interfaces) {
305 checkNotNull(router, "Router can not be null"); 434 checkNotNull(router, "Router can not be null");
306 - checkNotNull(routerInterfaces, "routerInterfaces can not be null"); 435 + checkNotNull(interfaces, "routerInterfaces can not be null");
307 Ip4Address externalIp = router.gatewayExternalInfo().externalFixedIps() 436 Ip4Address externalIp = router.gatewayExternalInfo().externalFixedIps()
308 .values().stream().findFirst().orElse(null); 437 .values().stream().findFirst().orElse(null);
309 if ((externalIp == null) || (!router.gatewayExternalInfo().isEnablePnat())) { 438 if ((externalIp == null) || (!router.gatewayExternalInfo().isEnablePnat())) {
310 log.debug("Not satisfied to set pnat configuration"); 439 log.debug("Not satisfied to set pnat configuration");
311 return; 440 return;
312 } 441 }
313 - routerInterfaces.forEach(routerInterface -> initiateL3Rule(router, routerInterface)); 442 + if (router.id() == null) {
443 + interfaces.forEach(i -> initiateL3Rule(getRouterfromExternalIp(externalIp), i));
444 + } else {
445 + interfaces.forEach(i -> initiateL3Rule(router, i));
446 + }
447 +
448 + }
449 +
450 + private OpenstackRouter getRouterfromExternalIp(Ip4Address externalIp) {
451 + OpenstackRouter router = getExternalRouter(true)
452 + .stream()
453 + .filter(r -> r.gatewayExternalInfo()
454 + .externalFixedIps()
455 + .values()
456 + .stream()
457 + .findFirst()
458 + .orElse(null)
459 + .equals(externalIp))
460 + .findAny()
461 + .orElse(null);
462 + return checkNotNull(router);
314 } 463 }
315 464
316 private void initiateL3Rule(OpenstackRouter router, OpenstackRouterInterface routerInterface) { 465 private void initiateL3Rule(OpenstackRouter router, OpenstackRouterInterface routerInterface) {
317 long vni = Long.parseLong(openstackService.network(openstackService 466 long vni = Long.parseLong(openstackService.network(openstackService
318 .port(routerInterface.portId()).networkId()).segmentId()); 467 .port(routerInterface.portId()).networkId()).segmentId());
319 - OpenstackRoutingRulePopulator rulePopulator = new OpenstackRoutingRulePopulator(appId,
320 - openstackService, flowObjectiveService, deviceService, driverService, config);
321 rulePopulator.populateExternalRules(vni, router, routerInterface); 468 rulePopulator.populateExternalRules(vni, router, routerInterface);
322 } 469 }
323 470
324 private Collection<OpenstackRouterInterface> getOpenstackRouterInterface(OpenstackRouter router) { 471 private Collection<OpenstackRouterInterface> getOpenstackRouterInterface(OpenstackRouter router) {
325 - return routerInterfaceMap.values().stream().filter(i -> i.id().equals(router.id())) 472 + List<OpenstackRouterInterface> interfaces = Lists.newArrayList();
326 - .collect(Collectors.toList()); 473 + openstackService.ports()
474 + .stream()
475 + .filter(p -> p.deviceOwner().equals(DEVICE_OWNER_ROUTER_INTERFACE))
476 + .filter(p -> p.deviceId().equals(router.id()))
477 + .forEach(p -> {
478 + OpenstackRouterInterface routerInterface = portToRouterInterface(p);
479 + interfaces.add(routerInterface);
480 + });
481 + return interfaces;
327 } 482 }
328 483
329 private OpenstackRouter getOpenstackRouter(String id) { 484 private OpenstackRouter getOpenstackRouter(String id) {
...@@ -334,8 +489,8 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -334,8 +489,8 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
334 private OpenstackPort getOpenstackPort(MacAddress sourceMac, Ip4Address ip4Address) { 489 private OpenstackPort getOpenstackPort(MacAddress sourceMac, Ip4Address ip4Address) {
335 OpenstackPort openstackPort = openstackService.ports().stream() 490 OpenstackPort openstackPort = openstackService.ports().stream()
336 .filter(p -> p.macAddress().equals(sourceMac)).findFirst().orElse(null); 491 .filter(p -> p.macAddress().equals(sourceMac)).findFirst().orElse(null);
337 - return checkNotNull(openstackPort.fixedIps().values().stream().findFirst().orElse(null)) 492 + return openstackPort.fixedIps().values().stream().filter(ip ->
338 - .equals(ip4Address) ? openstackPort : null; 493 + ip.equals(ip4Address)).count() > 0 ? openstackPort : null;
339 } 494 }
340 495
341 private void readConfiguration() { 496 private void readConfiguration() {
...@@ -353,7 +508,8 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -353,7 +508,8 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
353 log.debug("Configured info: {}, {}, {}, {}", config.physicalRouterMac(), config.gatewayBridgeId(), 508 log.debug("Configured info: {}, {}, {}, {}", config.physicalRouterMac(), config.gatewayBridgeId(),
354 config.gatewayExternalInterfaceMac(), config.gatewayExternalInterfaceName()); 509 config.gatewayExternalInterfaceMac(), config.gatewayExternalInterfaceName());
355 510
356 - reloadInitL3Rules(); 511 + rulePopulator = new OpenstackRoutingRulePopulator(appId,
512 + openstackService, flowObjectiveService, deviceService, driverService, config);
357 513
358 openstackIcmpHandler = new OpenstackIcmpHandler(packetService, deviceService, 514 openstackIcmpHandler = new OpenstackIcmpHandler(packetService, deviceService,
359 openstackService, config, openstackSwitchingService); 515 openstackService, config, openstackSwitchingService);
...@@ -361,7 +517,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -361,7 +517,7 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
361 517
362 openstackIcmpHandler.requestPacket(appId); 518 openstackIcmpHandler.requestPacket(appId);
363 openstackArpHandler.requestPacket(appId); 519 openstackArpHandler.requestPacket(appId);
364 - 520 + reloadInitL3Rules();
365 log.info("OpenstackRouting configured"); 521 log.info("OpenstackRouting configured");
366 } 522 }
367 523
...@@ -373,14 +529,12 @@ public class OpenstackRoutingManager implements OpenstackRoutingService { ...@@ -373,14 +529,12 @@ public class OpenstackRoutingManager implements OpenstackRoutingService {
373 return; 529 return;
374 } 530 }
375 531
376 - switch (event.type()) { 532 + if (event.type().equals(NetworkConfigEvent.Type.CONFIG_ADDED) ||
377 - case CONFIG_ADDED: 533 + event.type().equals(NetworkConfigEvent.Type.CONFIG_UPDATED)) {
378 - case CONFIG_UPDATED:
379 l3EventExecutorService.execute(OpenstackRoutingManager.this::readConfiguration); 534 l3EventExecutorService.execute(OpenstackRoutingManager.this::readConfiguration);
380 - break; 535 + rulePopulator = new OpenstackRoutingRulePopulator(appId,
381 - default: 536 + openstackService, flowObjectiveService, deviceService, driverService, config);
382 - log.debug("Unsupported event type {}", event.type().toString()); 537 +
383 - break;
384 } 538 }
385 } 539 }
386 } 540 }
......
...@@ -52,6 +52,8 @@ import org.onosproject.openstackinterface.OpenstackPort; ...@@ -52,6 +52,8 @@ import org.onosproject.openstackinterface.OpenstackPort;
52 import org.onosproject.openstackinterface.OpenstackRouter; 52 import org.onosproject.openstackinterface.OpenstackRouter;
53 import org.onosproject.openstackinterface.OpenstackRouterInterface; 53 import org.onosproject.openstackinterface.OpenstackRouterInterface;
54 import org.onosproject.openstackinterface.OpenstackSubnet; 54 import org.onosproject.openstackinterface.OpenstackSubnet;
55 +import org.onosproject.openstackinterface.OpenstackFloatingIP;
56 +import org.onosproject.openstacknetworking.OpenstackPortInfo;
55 import org.slf4j.Logger; 57 import org.slf4j.Logger;
56 import org.slf4j.LoggerFactory; 58 import org.slf4j.LoggerFactory;
57 59
...@@ -73,16 +75,17 @@ public class OpenstackRoutingRulePopulator { ...@@ -73,16 +75,17 @@ public class OpenstackRoutingRulePopulator {
73 private final DriverService driverService; 75 private final DriverService driverService;
74 private final OpenstackRoutingConfig config; 76 private final OpenstackRoutingConfig config;
75 77
76 - private static final String PORTNAME_PREFIX_VM = "tap";
77 - private static final String PORTNAME_PREFIX_ROUTER = "qr";
78 private static final String PORTNAME_PREFIX_TUNNEL = "vxlan"; 78 private static final String PORTNAME_PREFIX_TUNNEL = "vxlan";
79 private static final String PORTNAME = "portName"; 79 private static final String PORTNAME = "portName";
80 + private static final String PORTNAME_PREFIX_VM = "tap";
80 81
81 private static final String PORTNOTNULL = "Port can not be null"; 82 private static final String PORTNOTNULL = "Port can not be null";
83 + private static final String DEVICENOTNULL = "Device can not be null";
82 private static final String TUNNEL_DESTINATION = "tunnelDst"; 84 private static final String TUNNEL_DESTINATION = "tunnelDst";
83 private static final String DEVICE_ANNOTATION_CHANNELID = "channelId"; 85 private static final String DEVICE_ANNOTATION_CHANNELID = "channelId";
84 private static final int ROUTING_RULE_PRIORITY = 25000; 86 private static final int ROUTING_RULE_PRIORITY = 25000;
85 - private static final int PNAT_RULE_PRIORITY = 24000; 87 + private static final int FLOATING_RULE_PRIORITY = 42000;
88 + private static final int PNAT_RULE_PRIORITY = 26000;
86 private static final int PNAT_TIMEOUT = 120; 89 private static final int PNAT_TIMEOUT = 120;
87 private static final MacAddress GATEWAYMAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f"); 90 private static final MacAddress GATEWAYMAC = MacAddress.valueOf("1f:1f:1f:1f:1f:1f");
88 91
...@@ -134,7 +137,7 @@ public class OpenstackRoutingRulePopulator { ...@@ -134,7 +137,7 @@ public class OpenstackRoutingRulePopulator {
134 this.externalInterface = externalInterfaceMacAddress; 137 this.externalInterface = externalInterfaceMacAddress;
135 this.externalRouter = externalRouterMacAddress; 138 this.externalRouter = externalRouterMacAddress;
136 139
137 - long vni = getVni(openstackPort); 140 + long vni = getVni(openstackPort.networkId());
138 141
139 populatePnatIncomingFlowRules(vni, externalIp); 142 populatePnatIncomingFlowRules(vni, externalIp);
140 populatePnatOutgoingFlowRules(vni, externalIp); 143 populatePnatOutgoingFlowRules(vni, externalIp);
...@@ -173,7 +176,7 @@ public class OpenstackRoutingRulePopulator { ...@@ -173,7 +176,7 @@ public class OpenstackRoutingRulePopulator {
173 break; 176 break;
174 } 177 }
175 178
176 - Port port = checkNotNull(getPortNumOfExternalInterface(), PORTNOTNULL); 179 + Port port = checkNotNull(getPortOfExternalInterface(), PORTNOTNULL);
177 tBuilder.setOutput(port.number()); 180 tBuilder.setOutput(port.number());
178 181
179 ForwardingObjective fo = DefaultForwardingObjective.builder() 182 ForwardingObjective fo = DefaultForwardingObjective.builder()
...@@ -188,8 +191,8 @@ public class OpenstackRoutingRulePopulator { ...@@ -188,8 +191,8 @@ public class OpenstackRoutingRulePopulator {
188 flowObjectiveService.forward(inboundPacket.receivedFrom().deviceId(), fo); 191 flowObjectiveService.forward(inboundPacket.receivedFrom().deviceId(), fo);
189 } 192 }
190 193
191 - private Port getPortNumOfExternalInterface() { 194 + private Port getPortOfExternalInterface() {
192 - return deviceService.getPorts(inboundPacket.receivedFrom().deviceId()).stream() 195 + return deviceService.getPorts(getGatewayNode().id()).stream()
193 .filter(p -> p.annotations().value(PORTNAME).equals(config.gatewayExternalInterfaceName())) 196 .filter(p -> p.annotations().value(PORTNAME).equals(config.gatewayExternalInterfaceName()))
194 .findAny().orElse(null); 197 .findAny().orElse(null);
195 } 198 }
...@@ -207,6 +210,7 @@ public class OpenstackRoutingRulePopulator { ...@@ -207,6 +210,7 @@ public class OpenstackRoutingRulePopulator {
207 210
208 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); 211 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
209 tBuilder.setTunnelId(vni) 212 tBuilder.setTunnelId(vni)
213 + .setEthDst(inboundPacket.parsed().getSourceMAC())
210 .setIpDst(IpAddress.valueOf(iPacket.getSourceAddress())); 214 .setIpDst(IpAddress.valueOf(iPacket.getSourceAddress()));
211 215
212 switch (iPacket.getProtocol()) { 216 switch (iPacket.getProtocol()) {
...@@ -226,7 +230,7 @@ public class OpenstackRoutingRulePopulator { ...@@ -226,7 +230,7 @@ public class OpenstackRoutingRulePopulator {
226 break; 230 break;
227 } 231 }
228 232
229 - tBuilder.extension(buildNiciraExtenstion(deviceId, Ip4Address.valueOf(iPacket.getSourceAddress())), deviceId) 233 + tBuilder.extension(buildNiciraExtenstion(deviceId, getHostIpfromOpenstackPort(openstackPort)), deviceId)
230 .setOutput(getTunnelPort(deviceId)); 234 .setOutput(getTunnelPort(deviceId));
231 235
232 ForwardingObjective fo = DefaultForwardingObjective.builder() 236 ForwardingObjective fo = DefaultForwardingObjective.builder()
...@@ -241,14 +245,37 @@ public class OpenstackRoutingRulePopulator { ...@@ -241,14 +245,37 @@ public class OpenstackRoutingRulePopulator {
241 flowObjectiveService.forward(inboundPacket.receivedFrom().deviceId(), fo); 245 flowObjectiveService.forward(inboundPacket.receivedFrom().deviceId(), fo);
242 } 246 }
243 247
248 + private Ip4Address getHostIpfromOpenstackPort(OpenstackPort openstackPort) {
249 + Device device = getDevicefromOpenstackPort(openstackPort);
250 + return getIPAddressforDevice(device);
251 + }
252 +
253 + private Device getDevicefromOpenstackPort(OpenstackPort openstackPort) {
254 + String openstackPortName = PORTNAME_PREFIX_VM + openstackPort.id().substring(0, 11);
255 + Device device = StreamSupport.stream(deviceService.getDevices().spliterator(), false)
256 + .filter(d -> findPortinDevice(d, openstackPortName))
257 + .findAny()
258 + .orElse(null);
259 + checkNotNull(device, DEVICENOTNULL);
260 + return device;
261 + }
262 +
263 + private boolean findPortinDevice(Device d, String openstackPortName) {
264 + Port port = deviceService.getPorts(d.id())
265 + .stream()
266 + .filter(p -> p.isEnabled() && p.annotations().value(PORTNAME).equals(openstackPortName))
267 + .findAny()
268 + .orElse(null);
269 + return port != null ? true : false;
270 + }
271 +
244 /** 272 /**
245 - * Returns NiciraExtension treatment. 273 + * Builds NiciraExtension for tagging remoteIp of vxlan.
246 * 274 *
247 - * @param id device id 275 + * @param id Device Id of vxlan source device
248 - * @param hostIp host ip 276 + * @param hostIp Remote Ip of vxlan destination device
249 - * @return NiciraExtension treatment 277 + * @return NiciraExtension Treatment
250 */ 278 */
251 -
252 public ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) { 279 public ExtensionTreatment buildNiciraExtenstion(DeviceId id, Ip4Address hostIp) {
253 Driver driver = driverService.getDriver(id); 280 Driver driver = driverService.getDriver(id);
254 DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id)); 281 DriverHandler driverHandler = new DefaultDriverHandler(new DefaultDriverData(driver, id));
...@@ -270,8 +297,8 @@ public class OpenstackRoutingRulePopulator { ...@@ -270,8 +297,8 @@ public class OpenstackRoutingRulePopulator {
270 /** 297 /**
271 * Returns port number of vxlan tunnel. 298 * Returns port number of vxlan tunnel.
272 * 299 *
273 - * @param deviceId device id 300 + * @param deviceId Target Device Id
274 - * @return port number of vxlan tunnel 301 + * @return PortNumber
275 */ 302 */
276 public PortNumber getTunnelPort(DeviceId deviceId) { 303 public PortNumber getTunnelPort(DeviceId deviceId) {
277 Port port = deviceService.getPorts(deviceId).stream() 304 Port port = deviceService.getPorts(deviceId).stream()
...@@ -328,7 +355,7 @@ public class OpenstackRoutingRulePopulator { ...@@ -328,7 +355,7 @@ public class OpenstackRoutingRulePopulator {
328 private void populateComputeNodeRules(long vni) { 355 private void populateComputeNodeRules(long vni) {
329 Device gatewayDevice = getGatewayNode(); 356 Device gatewayDevice = getGatewayNode();
330 357
331 - StreamSupport.stream(deviceService.getAvailableDevices().spliterator(), false) 358 + StreamSupport.stream(deviceService.getDevices().spliterator(), false)
332 .filter(d -> !checkGatewayNode(d.id())) 359 .filter(d -> !checkGatewayNode(d.id()))
333 .forEach(d -> populateRuleToGateway(d, gatewayDevice, vni)); 360 .forEach(d -> populateRuleToGateway(d, gatewayDevice, vni));
334 } 361 }
...@@ -366,12 +393,8 @@ public class OpenstackRoutingRulePopulator { ...@@ -366,12 +393,8 @@ public class OpenstackRoutingRulePopulator {
366 return deviceId.toString().equals(config.gatewayBridgeId()); 393 return deviceId.toString().equals(config.gatewayBridgeId());
367 } 394 }
368 395
369 - private long getVni(OpenstackPort openstackPort) { 396 + private long getVni(String netId) {
370 - return Long.parseLong(openstackService.network(openstackPort.networkId()).segmentId()); 397 + return Long.parseLong(openstackService.network(netId).segmentId());
371 - }
372 -
373 - private long getVni(OpenstackSubnet openstackSubnet) {
374 - return Long.parseLong(openstackService.network(openstackSubnet.networkId()).segmentId());
375 } 398 }
376 399
377 /** 400 /**
...@@ -383,32 +406,122 @@ public class OpenstackRoutingRulePopulator { ...@@ -383,32 +406,122 @@ public class OpenstackRoutingRulePopulator {
383 OpenstackSubnet openstackSubnet = openstackService.subnet(routerInterface.subnetId()); 406 OpenstackSubnet openstackSubnet = openstackService.subnet(routerInterface.subnetId());
384 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder(); 407 TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
385 sBuilder.matchEthType(Ethernet.TYPE_IPV4) 408 sBuilder.matchEthType(Ethernet.TYPE_IPV4)
386 - .matchTunnelId(getVni(openstackSubnet)) 409 + .matchTunnelId(getVni(openstackSubnet.networkId()))
387 .matchEthDst(GATEWAYMAC); 410 .matchEthDst(GATEWAYMAC);
388 411
389 - StreamSupport.stream(deviceService.getAvailableDevices().spliterator(), false) 412 + StreamSupport.stream(deviceService.getDevices().spliterator(), false)
390 .forEach(d -> { 413 .forEach(d -> {
391 if (checkGatewayNode(d.id())) { 414 if (checkGatewayNode(d.id())) {
392 - removeExternalRule(d.id(), sBuilder, ForwardingObjective.Flag.VERSATILE); 415 + removeRule(d.id(), sBuilder, ForwardingObjective.Flag.VERSATILE, ROUTING_RULE_PRIORITY);
393 } else { 416 } else {
394 - removeExternalRule(d.id(), sBuilder, ForwardingObjective.Flag.SPECIFIC); 417 + removeRule(d.id(), sBuilder, ForwardingObjective.Flag.SPECIFIC, ROUTING_RULE_PRIORITY);
395 } 418 }
396 }); 419 });
397 420
398 } 421 }
399 422
400 - private void removeExternalRule(DeviceId id, TrafficSelector.Builder sBuilder, ForwardingObjective.Flag flag) { 423 + private void removeRule(DeviceId id, TrafficSelector.Builder sBuilder,
424 + ForwardingObjective.Flag flag, int priority) {
401 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder(); 425 TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
402 426
403 ForwardingObjective fo = DefaultForwardingObjective.builder() 427 ForwardingObjective fo = DefaultForwardingObjective.builder()
404 .withSelector(sBuilder.build()) 428 .withSelector(sBuilder.build())
405 .withTreatment(tBuilder.build()) 429 .withTreatment(tBuilder.build())
406 .withFlag(flag) 430 .withFlag(flag)
407 - .withPriority(ROUTING_RULE_PRIORITY) 431 + .withPriority(priority)
408 .fromApp(appId) 432 .fromApp(appId)
409 .remove(); 433 .remove();
410 434
411 flowObjectiveService.forward(id, fo); 435 flowObjectiveService.forward(id, fo);
412 } 436 }
413 437
438 + /**
439 + * Populates flow rules for floatingIp configuration.
440 + *
441 + * @param floatingIP Corresponding floating ip information
442 + */
443 + public void populateFloatingIpRules(OpenstackFloatingIP floatingIP) {
444 + OpenstackPort port = openstackService.port(floatingIP.portId());
445 + //1. incoming rules
446 + populateFloatingIpIncomingRules(floatingIP, port);
447 + //2. outgoing rules
448 + populateFloatingIpOutgoingRules(floatingIP, port);
449 + }
450 +
451 + private void populateFloatingIpIncomingRules(OpenstackFloatingIP floatingIP, OpenstackPort port) {
452 + DeviceId portDeviceId = getDevicefromOpenstackPort(port).id();
453 + Device gatewayNode = getGatewayNode();
454 + Device portNode = deviceService.getDevice(portDeviceId);
455 +
456 + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
457 + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
458 +
459 + sBuilder.matchEthType(Ethernet.TYPE_IPV4)
460 + .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), 32));
461 +
462 + tBuilder.setEthSrc(MacAddress.valueOf(config.gatewayExternalInterfaceMac()))
463 + .setEthDst(port.macAddress())
464 + .setIpDst(floatingIP.fixedIpAddress())
465 + .setTunnelId(getVni(port.networkId()))
466 + .extension(buildNiciraExtenstion(gatewayNode.id(), getIPAddressforDevice(portNode)), gatewayNode.id())
467 + .setOutput(getTunnelPort(gatewayNode.id()));
468 +
469 + ForwardingObjective fo = DefaultForwardingObjective.builder()
470 + .withSelector(sBuilder.build())
471 + .withTreatment(tBuilder.build())
472 + .withFlag(ForwardingObjective.Flag.VERSATILE)
473 + .withPriority(FLOATING_RULE_PRIORITY)
474 + .fromApp(appId)
475 + .add();
476 +
477 + flowObjectiveService.forward(getGatewayNode().id(), fo);
478 +
479 + }
480 +
481 + private void populateFloatingIpOutgoingRules(OpenstackFloatingIP floatingIP, OpenstackPort port) {
482 + Port outputPort = checkNotNull(getPortOfExternalInterface(), PORTNOTNULL);
483 +
484 + TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder();
485 + TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
486 +
487 + sBuilder.matchEthType(Ethernet.TYPE_IPV4)
488 + .matchTunnelId(getVni(port.networkId()))
489 + .matchIPSrc(IpPrefix.valueOf(floatingIP.fixedIpAddress(), 32));
490 +
491 + tBuilder.setIpSrc(floatingIP.floatingIpAddress())
492 + .setEthSrc(MacAddress.valueOf(config.gatewayExternalInterfaceMac()))
493 + .setEthDst(MacAddress.valueOf(config.physicalRouterMac()))
494 + .setOutput(outputPort.number());
495 +
496 + ForwardingObjective fo = DefaultForwardingObjective.builder()
497 + .withSelector(sBuilder.build())
498 + .withTreatment(tBuilder.build())
499 + .withFlag(ForwardingObjective.Flag.VERSATILE)
500 + .withPriority(FLOATING_RULE_PRIORITY)
501 + .fromApp(appId)
502 + .add();
503 +
504 + flowObjectiveService.forward(getGatewayNode().id(), fo);
505 + }
506 +
507 + /**
508 + * Removes flow rules for floating ip configuration.
509 + *
510 + * @param floatingIP Corresponding floating ip information
511 + */
512 + public void removeFloatingIpRules(OpenstackFloatingIP floatingIP, OpenstackPortInfo portInfo) {
513 + TrafficSelector.Builder sOutgoingBuilder = DefaultTrafficSelector.builder();
514 + TrafficSelector.Builder sIncomingBuilder = DefaultTrafficSelector.builder();
515 +
516 + sOutgoingBuilder.matchEthType(Ethernet.TYPE_IPV4)
517 + .matchTunnelId(portInfo.vni())
518 + .matchIPSrc(IpPrefix.valueOf(portInfo.ip(), 32));
519 +
520 + sIncomingBuilder.matchEthType(Ethernet.TYPE_IPV4)
521 + .matchIPDst(IpPrefix.valueOf(floatingIP.floatingIpAddress(), 32));
522 +
523 + removeRule(getGatewayNode().id(), sOutgoingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY);
524 + removeRule(getGatewayNode().id(), sIncomingBuilder, ForwardingObjective.Flag.VERSATILE, FLOATING_RULE_PRIORITY);
525 + }
526 +
414 } 527 }
......
...@@ -19,6 +19,8 @@ import com.fasterxml.jackson.databind.ObjectMapper; ...@@ -19,6 +19,8 @@ import com.fasterxml.jackson.databind.ObjectMapper;
19 import com.fasterxml.jackson.databind.node.ObjectNode; 19 import com.fasterxml.jackson.databind.node.ObjectNode;
20 import org.onosproject.openstackinterface.OpenstackPort; 20 import org.onosproject.openstackinterface.OpenstackPort;
21 import org.onosproject.openstackinterface.web.OpenstackPortCodec; 21 import org.onosproject.openstackinterface.web.OpenstackPortCodec;
22 +import org.onosproject.openstacknetworking.OpenstackPortInfo;
23 +import org.onosproject.openstacknetworking.OpenstackRoutingService;
22 import org.onosproject.openstacknetworking.OpenstackSwitchingService; 24 import org.onosproject.openstacknetworking.OpenstackSwitchingService;
23 import org.onosproject.rest.AbstractWebResource; 25 import org.onosproject.rest.AbstractWebResource;
24 import org.slf4j.Logger; 26 import org.slf4j.Logger;
...@@ -42,7 +44,7 @@ import java.io.InputStream; ...@@ -42,7 +44,7 @@ import java.io.InputStream;
42 public class OpenstackPortWebResource extends AbstractWebResource { 44 public class OpenstackPortWebResource extends AbstractWebResource {
43 45
44 private final Logger log = LoggerFactory.getLogger(getClass()); 46 private final Logger log = LoggerFactory.getLogger(getClass());
45 - 47 + private static final String PORTNAME_PREFIX_VM = "tap";
46 private static final OpenstackPortCodec PORT_CODEC = new OpenstackPortCodec(); 48 private static final OpenstackPortCodec PORT_CODEC = new OpenstackPortCodec();
47 49
48 @POST 50 @POST
...@@ -75,7 +77,14 @@ public class OpenstackPortWebResource extends AbstractWebResource { ...@@ -75,7 +77,14 @@ public class OpenstackPortWebResource extends AbstractWebResource {
75 public Response deletePorts(@PathParam("portUUID") String id) { 77 public Response deletePorts(@PathParam("portUUID") String id) {
76 OpenstackSwitchingService switchingService = 78 OpenstackSwitchingService switchingService =
77 getService(OpenstackSwitchingService.class); 79 getService(OpenstackSwitchingService.class);
80 + OpenstackPortInfo portInfo = switchingService.openstackPortInfo()
81 + .get(PORTNAME_PREFIX_VM.concat(id.substring(0, 11)));
82 + OpenstackRoutingService routingService =
83 + getService(OpenstackRoutingService.class);
84 + routingService.checkDisassociatedFloatingIp(id, portInfo);
85 +
78 switchingService.removePort(id); 86 switchingService.removePort(id);
87 +
79 return Response.status(Response.Status.OK).build(); 88 return Response.status(Response.Status.OK).build();
80 } 89 }
81 90
......