lishuai
Committed by Gerrit Code Review

[ONOS-3520] Add L3 codes for VTNManager class.

Change-Id: I86b5b6e2b863fa78759272e1c8c212017b6a696f
...@@ -17,6 +17,7 @@ package org.onosproject.vtn.manager; ...@@ -17,6 +17,7 @@ package org.onosproject.vtn.manager;
17 17
18 import org.onosproject.net.Device; 18 import org.onosproject.net.Device;
19 import org.onosproject.net.Host; 19 import org.onosproject.net.Host;
20 +import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
20 21
21 /** 22 /**
22 * VTN application that applies configuration and flows to the device. 23 * VTN application that applies configuration and flows to the device.
...@@ -67,4 +68,32 @@ public interface VTNService { ...@@ -67,4 +68,32 @@ public interface VTNService {
67 */ 68 */
68 void onHostVanished(Host host); 69 void onHostVanished(Host host);
69 70
71 + /**
72 + * Applies east west flows when neutron created router interface.
73 + *
74 + * @param l3Feedback VtnrscEventFeedback
75 + */
76 + void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback);
77 +
78 + /**
79 + * Remove east west flows when neutron removed router interface.
80 + *
81 + * @param l3Feedback VtnrscEventFeedback
82 + */
83 + void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback);
84 +
85 + /**
86 + * Applies north south flows when neutron bind floating ip.
87 + *
88 + * @param l3Feedback VtnrscEventFeedback
89 + */
90 + void onFloatingIpDetected(VtnRscEventFeedback l3Feedback);
91 +
92 + /**
93 + * Applies north south flows when neutron unbind floating ip.
94 + *
95 + * @param l3Feedback VtnrscEventFeedback
96 + */
97 + void onFloatingIpVanished(VtnRscEventFeedback l3Feedback);
98 +
70 } 99 }
......
...@@ -18,6 +18,7 @@ package org.onosproject.vtn.manager.impl; ...@@ -18,6 +18,7 @@ package org.onosproject.vtn.manager.impl;
18 import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; 18 import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST;
19 import static org.slf4j.LoggerFactory.getLogger; 19 import static org.slf4j.LoggerFactory.getLogger;
20 20
21 +import java.util.ArrayList;
21 import java.util.Collection; 22 import java.util.Collection;
22 import java.util.HashMap; 23 import java.util.HashMap;
23 import java.util.HashSet; 24 import java.util.HashSet;
...@@ -25,6 +26,7 @@ import java.util.Iterator; ...@@ -25,6 +26,7 @@ import java.util.Iterator;
25 import java.util.List; 26 import java.util.List;
26 import java.util.Map; 27 import java.util.Map;
27 import java.util.Set; 28 import java.util.Set;
29 +import java.util.stream.Collectors;
28 30
29 import org.apache.felix.scr.annotations.Activate; 31 import org.apache.felix.scr.annotations.Activate;
30 import org.apache.felix.scr.annotations.Component; 32 import org.apache.felix.scr.annotations.Component;
...@@ -39,9 +41,11 @@ import org.onlab.util.KryoNamespace; ...@@ -39,9 +41,11 @@ import org.onlab.util.KryoNamespace;
39 import org.onosproject.core.ApplicationId; 41 import org.onosproject.core.ApplicationId;
40 import org.onosproject.core.CoreService; 42 import org.onosproject.core.CoreService;
41 import org.onosproject.mastership.MastershipService; 43 import org.onosproject.mastership.MastershipService;
44 +import org.onosproject.net.AnnotationKeys;
42 import org.onosproject.net.Device; 45 import org.onosproject.net.Device;
43 import org.onosproject.net.DeviceId; 46 import org.onosproject.net.DeviceId;
44 import org.onosproject.net.Host; 47 import org.onosproject.net.Host;
48 +import org.onosproject.net.HostId;
45 import org.onosproject.net.Port; 49 import org.onosproject.net.Port;
46 import org.onosproject.net.PortNumber; 50 import org.onosproject.net.PortNumber;
47 import org.onosproject.net.behaviour.BridgeConfig; 51 import org.onosproject.net.behaviour.BridgeConfig;
...@@ -74,8 +78,12 @@ import org.onosproject.store.service.EventuallyConsistentMap; ...@@ -74,8 +78,12 @@ import org.onosproject.store.service.EventuallyConsistentMap;
74 import org.onosproject.store.service.LogicalClockService; 78 import org.onosproject.store.service.LogicalClockService;
75 import org.onosproject.store.service.StorageService; 79 import org.onosproject.store.service.StorageService;
76 import org.onosproject.vtn.manager.VTNService; 80 import org.onosproject.vtn.manager.VTNService;
81 +import org.onosproject.vtn.table.ArpService;
77 import org.onosproject.vtn.table.ClassifierService; 82 import org.onosproject.vtn.table.ClassifierService;
83 +import org.onosproject.vtn.table.DnatService;
78 import org.onosproject.vtn.table.L2ForwardService; 84 import org.onosproject.vtn.table.L2ForwardService;
85 +import org.onosproject.vtn.table.L3ForwardService;
86 +import org.onosproject.vtn.table.SnatService;
79 import org.onosproject.vtn.table.impl.ClassifierServiceImpl; 87 import org.onosproject.vtn.table.impl.ClassifierServiceImpl;
80 import org.onosproject.vtn.table.impl.L2ForwardServiceImpl; 88 import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
81 import org.onosproject.vtn.util.DataPathIdGenerator; 89 import org.onosproject.vtn.util.DataPathIdGenerator;
...@@ -85,6 +93,11 @@ import org.onosproject.vtnrsc.AllowedAddressPair; ...@@ -85,6 +93,11 @@ import org.onosproject.vtnrsc.AllowedAddressPair;
85 import org.onosproject.vtnrsc.BindingHostId; 93 import org.onosproject.vtnrsc.BindingHostId;
86 import org.onosproject.vtnrsc.DefaultVirtualPort; 94 import org.onosproject.vtnrsc.DefaultVirtualPort;
87 import org.onosproject.vtnrsc.FixedIp; 95 import org.onosproject.vtnrsc.FixedIp;
96 +import org.onosproject.vtnrsc.FloatingIp;
97 +import org.onosproject.vtnrsc.Router;
98 +import org.onosproject.vtnrsc.RouterGateway;
99 +import org.onosproject.vtnrsc.RouterId;
100 +import org.onosproject.vtnrsc.RouterInterface;
88 import org.onosproject.vtnrsc.SecurityGroup; 101 import org.onosproject.vtnrsc.SecurityGroup;
89 import org.onosproject.vtnrsc.SegmentationId; 102 import org.onosproject.vtnrsc.SegmentationId;
90 import org.onosproject.vtnrsc.SubnetId; 103 import org.onosproject.vtnrsc.SubnetId;
...@@ -93,6 +106,14 @@ import org.onosproject.vtnrsc.TenantNetwork; ...@@ -93,6 +106,14 @@ import org.onosproject.vtnrsc.TenantNetwork;
93 import org.onosproject.vtnrsc.TenantNetworkId; 106 import org.onosproject.vtnrsc.TenantNetworkId;
94 import org.onosproject.vtnrsc.VirtualPort; 107 import org.onosproject.vtnrsc.VirtualPort;
95 import org.onosproject.vtnrsc.VirtualPortId; 108 import org.onosproject.vtnrsc.VirtualPortId;
109 +import org.onosproject.vtnrsc.event.VtnRscEvent;
110 +import org.onosproject.vtnrsc.event.VtnRscEventFeedback;
111 +import org.onosproject.vtnrsc.event.VtnRscListener;
112 +import org.onosproject.vtnrsc.floatingip.FloatingIpService;
113 +import org.onosproject.vtnrsc.router.RouterService;
114 +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService;
115 +import org.onosproject.vtnrsc.service.VtnRscService;
116 +import org.onosproject.vtnrsc.subnet.SubnetService;
96 import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; 117 import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService;
97 import org.onosproject.vtnrsc.virtualport.VirtualPortService; 118 import org.onosproject.vtnrsc.virtualport.VirtualPortService;
98 import org.slf4j.Logger; 119 import org.slf4j.Logger;
...@@ -142,12 +163,32 @@ public class VTNManager implements VTNService { ...@@ -142,12 +163,32 @@ public class VTNManager implements VTNService {
142 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 163 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
143 protected GroupService groupService; 164 protected GroupService groupService;
144 165
166 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
167 + protected SubnetService subnetService;
168 +
169 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
170 + protected VtnRscService vtnRscService;
171 +
172 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
173 + protected FloatingIpService floatingIpService;
174 +
175 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
176 + protected RouterService routerService;
177 +
178 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
179 + protected RouterInterfaceService routerInterfaceService;
180 +
145 private ApplicationId appId; 181 private ApplicationId appId;
146 private ClassifierService classifierService; 182 private ClassifierService classifierService;
147 private L2ForwardService l2ForwardService; 183 private L2ForwardService l2ForwardService;
184 + private ArpService arpService;
185 + private L3ForwardService l3ForwardService;
186 + private SnatService snatService;
187 + private DnatService dnatService;
148 188
149 private final HostListener hostListener = new InnerHostListener(); 189 private final HostListener hostListener = new InnerHostListener();
150 private final DeviceListener deviceListener = new InnerDeviceListener(); 190 private final DeviceListener deviceListener = new InnerDeviceListener();
191 + private final VtnRscListener l3EventListener = new VtnL3EventListener();
151 192
152 private static final String IFACEID = "ifaceid"; 193 private static final String IFACEID = "ifaceid";
153 private static final String CONTROLLER_IP_KEY = "ipaddress"; 194 private static final String CONTROLLER_IP_KEY = "ipaddress";
...@@ -156,11 +197,19 @@ public class VTNManager implements VTNService { ...@@ -156,11 +197,19 @@ public class VTNManager implements VTNService {
156 private static final String VIRTUALPORT = "vtn-virtual-port"; 197 private static final String VIRTUALPORT = "vtn-virtual-port";
157 private static final String SWITCHES_OF_CONTROLLER = "switchesOfController"; 198 private static final String SWITCHES_OF_CONTROLLER = "switchesOfController";
158 private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts"; 199 private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts";
200 + private static final String ROUTERINF_FLAG_OF_TENANT = "routerInfFlagOfTenant";
201 + private static final String HOSTS_OF_SUBNET = "hostsOfSubnet";
202 + private static final String EX_PORT_OF_DEVICE = "exPortOfDevice";
159 private static final String DEFAULT_IP = "0.0.0.0"; 203 private static final String DEFAULT_IP = "0.0.0.0";
204 + private static final String PORT_MAC = "portMac";
205 + private static final int SUBNET_NUM = 2;
160 206
161 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore; 207 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
162 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController; 208 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
163 private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts; 209 private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts;
210 + private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet;
211 + private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant;
212 + private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice;
164 213
165 @Activate 214 @Activate
166 public void activate() { 215 public void activate() {
...@@ -206,6 +255,24 @@ public class VTNManager implements VTNService { ...@@ -206,6 +255,24 @@ public class VTNManager implements VTNService {
206 .withTimestampProvider((k, v) -> clockService.getTimestamp()) 255 .withTimestampProvider((k, v) -> clockService.getTimestamp())
207 .build(); 256 .build();
208 257
258 + hostsOfSubnet = storageService
259 + .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder()
260 + .withName(HOSTS_OF_SUBNET).withSerializer(serializer)
261 + .withTimestampProvider((k, v) -> clockService.getTimestamp())
262 + .build();
263 +
264 + routerInfFlagOfTenant = storageService
265 + .<TenantId, Boolean>eventuallyConsistentMapBuilder()
266 + .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer)
267 + .withTimestampProvider((k, v) -> clockService.getTimestamp())
268 + .build();
269 +
270 + exPortOfDevice = storageService
271 + .<DeviceId, Port>eventuallyConsistentMapBuilder()
272 + .withName(EX_PORT_OF_DEVICE).withSerializer(serializer)
273 + .withTimestampProvider((k, v) -> clockService.getTimestamp())
274 + .build();
275 +
209 log.info("Started"); 276 log.info("Started");
210 } 277 }
211 278
...@@ -213,6 +280,7 @@ public class VTNManager implements VTNService { ...@@ -213,6 +280,7 @@ public class VTNManager implements VTNService {
213 public void deactivate() { 280 public void deactivate() {
214 deviceService.removeListener(deviceListener); 281 deviceService.removeListener(deviceListener);
215 hostService.removeListener(hostListener); 282 hostService.removeListener(hostListener);
283 + vtnRscService.removeListener(l3EventListener);
216 log.info("Stopped"); 284 log.info("Stopped");
217 } 285 }
218 286
...@@ -278,14 +346,36 @@ public class VTNManager implements VTNService { ...@@ -278,14 +346,36 @@ public class VTNManager implements VTNService {
278 346
279 @Override 347 @Override
280 public void onHostDetected(Host host) { 348 public void onHostDetected(Host host) {
349 + DeviceId deviceId = host.location().deviceId();
350 + if (!mastershipService.isLocalMaster(deviceId)) {
351 + return;
352 + }
353 + String ifaceId = host.annotations().value(IFACEID);
354 + if (ifaceId == null) {
355 + log.error("The ifaceId of Host is null");
356 + return;
357 + }
281 // apply L2 openflow rules 358 // apply L2 openflow rules
282 applyHostMonitoredL2Rules(host, Objective.Operation.ADD); 359 applyHostMonitoredL2Rules(host, Objective.Operation.ADD);
360 + // apply L3 openflow rules
361 + applyHostMonitoredL3Rules(host, Objective.Operation.ADD);
283 } 362 }
284 363
285 @Override 364 @Override
286 public void onHostVanished(Host host) { 365 public void onHostVanished(Host host) {
366 + DeviceId deviceId = host.location().deviceId();
367 + if (!mastershipService.isLocalMaster(deviceId)) {
368 + return;
369 + }
370 + String ifaceId = host.annotations().value(IFACEID);
371 + if (ifaceId == null) {
372 + log.error("The ifaceId of Host is null");
373 + return;
374 + }
287 // apply L2 openflow rules 375 // apply L2 openflow rules
288 applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE); 376 applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE);
377 + // apply L3 openflow rules
378 + applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE);
289 } 379 }
290 380
291 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp, 381 private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp,
...@@ -376,7 +466,7 @@ public class VTNManager implements VTNService { ...@@ -376,7 +466,7 @@ public class VTNManager implements VTNService {
376 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId); 466 VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId);
377 VirtualPort virtualPort = virtualPortService.getPort(virtualPortId); 467 VirtualPort virtualPort = virtualPortService.getPort(virtualPortId);
378 if (virtualPort == null) { 468 if (virtualPort == null) {
379 - virtualPort = vPortStore.get(virtualPortId); 469 + virtualPort = VtnData.getPort(vPortStore, virtualPortId);
380 } 470 }
381 471
382 Iterable<Device> devices = deviceService.getAvailableDevices(); 472 Iterable<Device> devices = deviceService.getAvailableDevices();
...@@ -582,4 +672,388 @@ public class VTNManager implements VTNService { ...@@ -582,4 +672,388 @@ public class VTNManager implements VTNService {
582 appid); 672 appid);
583 groupService.addGroup(groupDescription); 673 groupService.addGroup(groupDescription);
584 } 674 }
675 +
676 + private class VtnL3EventListener implements VtnRscListener {
677 + @Override
678 + public void event(VtnRscEvent event) {
679 + VtnRscEventFeedback l3Feedback = event.subject();
680 + if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) {
681 + onRouterInterfaceDetected(l3Feedback);
682 + } else
683 + if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) {
684 + onRouterInterfaceVanished(l3Feedback);
685 + } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) {
686 + onFloatingIpDetected(l3Feedback);
687 + } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) {
688 + onFloatingIpVanished(l3Feedback);
689 + }
690 + }
691 +
692 + }
693 +
694 + @Override
695 + public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) {
696 + Objective.Operation operation = Objective.Operation.ADD;
697 + RouterInterface routerInf = l3Feedback.routerInterface();
698 + Iterable<RouterInterface> interfaces = routerInterfaceService
699 + .getRouterInterfaces();
700 + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
701 + .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
702 + .collect(Collectors.toSet());
703 + if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
704 + programRouterInterface(routerInf, operation);
705 + } else {
706 + if (interfacesSet.size() >= SUBNET_NUM) {
707 + programInterfacesSet(interfacesSet, operation);
708 + }
709 + }
710 + }
711 +
712 + @Override
713 + public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) {
714 + Objective.Operation operation = Objective.Operation.REMOVE;
715 + RouterInterface routerInf = l3Feedback.routerInterface();
716 + Iterable<RouterInterface> interfaces = routerInterfaceService
717 + .getRouterInterfaces();
718 + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
719 + .stream().filter(r -> r.tenantId().equals(routerInf.tenantId()))
720 + .collect(Collectors.toSet());
721 + if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) {
722 + programRouterInterface(routerInf, operation);
723 + if (interfacesSet.size() == 1) {
724 + routerInfFlagOfTenant.remove(routerInf.tenantId());
725 + interfacesSet.stream().forEach(r -> {
726 + programRouterInterface(r, operation);
727 + });
728 + }
729 + }
730 + }
731 +
732 + @Override
733 + public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
734 + programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT);
735 + }
736 +
737 + @Override
738 + public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
739 + programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE);
740 + }
741 +
742 + private void programInterfacesSet(Set<RouterInterface> interfacesSet,
743 + Objective.Operation operation) {
744 + int subnetVmNum = 0;
745 + for (RouterInterface r : interfacesSet) {
746 + // Get all the host of the subnet
747 + Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId());
748 + if (hosts.size() > 0) {
749 + subnetVmNum++;
750 + if (subnetVmNum >= SUBNET_NUM) {
751 + routerInfFlagOfTenant.put(r.tenantId(), true);
752 + interfacesSet.stream().forEach(f -> {
753 + programRouterInterface(f, operation);
754 + });
755 + break;
756 + }
757 + }
758 + }
759 + }
760 +
761 + private void programRouterInterface(RouterInterface routerInf,
762 + Objective.Operation operation) {
763 + SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId());
764 + // Get all the host of the subnet
765 + Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId());
766 + hosts.values().stream().forEach(h -> {
767 + applyEastWestL3Flows(h, l3vni, operation);
768 + });
769 + }
770 +
771 + private void applyEastWestL3Flows(Host h, SegmentationId l3vni,
772 + Objective.Operation operation) {
773 + if (!mastershipService.isLocalMaster(h.location().deviceId())) {
774 + log.debug("not master device:{}", h.location().deviceId());
775 + return;
776 + }
777 + String ifaceId = h.annotations().value(IFACEID);
778 + VirtualPort hPort = virtualPortService
779 + .getPort(VirtualPortId.portId(ifaceId));
780 + if (hPort == null) {
781 + hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId));
782 + }
783 + IpAddress srcIp = null;
784 + IpAddress srcGwIp = null;
785 + MacAddress srcVmGwMac = null;
786 + SubnetId srcSubnetId = null;
787 + Iterator<FixedIp> srcIps = hPort.fixedIps().iterator();
788 + if (srcIps.hasNext()) {
789 + FixedIp fixedIp = srcIps.next();
790 + srcIp = fixedIp.ip();
791 + srcSubnetId = fixedIp.subnetId();
792 + srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp();
793 + FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp);
794 + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
795 + if (gwPort == null) {
796 + gwPort = VtnData.getPort(vPortStore, fixedGwIp);
797 + }
798 + srcVmGwMac = gwPort.macAddress();
799 + }
800 + TenantNetwork network = tenantNetworkService
801 + .getNetwork(hPort.networkId());
802 + // Classifier rules
803 + classifierService
804 + .programL3InPortClassifierRules(h.location().deviceId(),
805 + h.location().port(), h.mac(),
806 + srcVmGwMac, l3vni, operation);
807 + // Arp rules
808 + if (operation == Objective.Operation.ADD) {
809 + classifierService.programArpClassifierRules(h.location().deviceId(),
810 + srcGwIp,
811 + network.segmentationId(),
812 + operation);
813 + DriverHandler handler = driverService.createHandler(h.location().deviceId());
814 + arpService.programArpRules(handler, h.location().deviceId(), srcGwIp,
815 + network.segmentationId(), srcVmGwMac,
816 + operation);
817 + }
818 + Iterable<Device> devices = deviceService.getAvailableDevices();
819 + IpAddress srcArpIp = srcIp;
820 + MacAddress srcArpGwMac = srcVmGwMac;
821 + Sets.newHashSet(devices).stream()
822 + .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> {
823 + // L3FWD rules
824 + l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp,
825 + network.segmentationId(),
826 + srcArpGwMac, h.mac(),
827 + operation);
828 + });
829 + }
830 +
831 + private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback,
832 + VtnRscEvent.Type type) {
833 + FloatingIp floaingIp = l3Feedback.floatingIp();
834 + if (floaingIp != null) {
835 + VirtualPortId vmPortId = floaingIp.portId();
836 + VirtualPort vmPort = virtualPortService.getPort(vmPortId);
837 + VirtualPort fipPort = virtualPortService
838 + .getPort(floaingIp.networkId(), floaingIp.floatingIp());
839 + if (vmPort == null) {
840 + vmPort = VtnData.getPort(vPortStore, vmPortId);
841 + }
842 + if (fipPort == null) {
843 + fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(),
844 + floaingIp.floatingIp());
845 + }
846 + Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
847 + Host host = null;
848 + for (Host h : hostSet) {
849 + String ifaceid = h.annotations().value(IFACEID);
850 + if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
851 + host = h;
852 + break;
853 + }
854 + }
855 + if (host != null && vmPort != null && fipPort != null) {
856 + DeviceId deviceId = host.location().deviceId();
857 + Port exPort = exPortOfDevice.get(deviceId);
858 + SegmentationId l3vni = vtnRscService
859 + .getL3vni(vmPort.tenantId());
860 + // Floating ip BIND
861 + if (type == VtnRscEvent.Type.FLOATINGIP_PUT) {
862 + applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
863 + floaingIp, l3vni, exPort,
864 + Objective.Operation.ADD);
865 + } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) {
866 + // Floating ip UNBIND
867 + applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort,
868 + floaingIp, l3vni, exPort,
869 + Objective.Operation.REMOVE);
870 + }
871 + }
872 + }
873 + }
874 +
875 + private void applyNorthSouthL3Flows(DeviceId deviceId, Host host,
876 + VirtualPort vmPort, VirtualPort fipPort,
877 + FloatingIp floatingIp,
878 + SegmentationId l3Vni, Port exPort,
879 + Objective.Operation operation) {
880 + if (!mastershipService.isLocalMaster(deviceId)) {
881 + log.debug("not master device:{}", deviceId);
882 + return;
883 + }
884 + List gwIpMac = getGwIpAndMac(vmPort);
885 + IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
886 + MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
887 + FixedIp fixedGwIp = getGwFixedIp(floatingIp);
888 + MacAddress fGwMac = null;
889 + if (fixedGwIp != null) {
890 + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
891 + if (gwPort == null) {
892 + gwPort = VtnData.getPort(vPortStore, fixedGwIp);
893 + }
894 + fGwMac = gwPort.macAddress();
895 + }
896 + TenantNetwork vmNetwork = tenantNetworkService
897 + .getNetwork(vmPort.networkId());
898 + TenantNetwork fipNetwork = tenantNetworkService
899 + .getNetwork(fipPort.networkId());
900 + // L3 downlink traffic flow
901 + MacAddress exPortMac = MacAddress.valueOf(exPort.annotations().value(PORT_MAC));
902 + classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
903 + fipNetwork.segmentationId(),
904 + operation);
905 + classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
906 + floatingIp.floatingIp(), operation);
907 + DriverHandler handler = driverService.createHandler(deviceId);
908 + arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
909 + fipNetwork.segmentationId(), exPortMac,
910 + operation);
911 + dnatService.programRules(deviceId, floatingIp.floatingIp(),
912 + fGwMac, floatingIp.fixedIp(),
913 + l3Vni, operation);
914 + l3ForwardService
915 + .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(),
916 + vmNetwork.segmentationId(), dstVmGwMac,
917 + vmPort.macAddress(), operation);
918 +
919 + // L3 uplink traffic flow
920 + classifierService.programL3InPortClassifierRules(deviceId,
921 + host.location().port(),
922 + host.mac(), dstVmGwMac,
923 + l3Vni, operation);
924 + snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(),
925 + fGwMac, exPortMac,
926 + floatingIp.floatingIp(),
927 + fipNetwork.segmentationId(), operation);
928 + if (operation == Objective.Operation.ADD) {
929 + classifierService.programArpClassifierRules(deviceId, dstVmGwIp,
930 + vmNetwork.segmentationId(),
931 + operation);
932 + arpService.programArpRules(handler, deviceId, dstVmGwIp,
933 + vmNetwork.segmentationId(), dstVmGwMac,
934 + operation);
935 + l2ForwardService.programLocalOut(deviceId,
936 + fipNetwork.segmentationId(),
937 + exPort.number(), fGwMac, operation);
938 + }
939 + }
940 +
941 + private Port getExPort(DeviceId deviceId) {
942 + List<Port> ports = deviceService.getPorts(deviceId);
943 + Port exPort = null;
944 + for (Port port : ports) {
945 + String portName = port.annotations().value(AnnotationKeys.PORT_NAME);
946 + if (portName != null && portName.equals(EX_PORT_NAME)) {
947 + exPort = port;
948 + break;
949 + }
950 + }
951 + return exPort;
952 + }
953 +
954 + private List getGwIpAndMac(VirtualPort port) {
955 + List list = new ArrayList();
956 + MacAddress gwMac = null;
957 + SubnetId subnetId = null;
958 + IpAddress gwIp = null;
959 + Iterator<FixedIp> fixips = port.fixedIps().iterator();
960 + if (fixips.hasNext()) {
961 + FixedIp fixip = fixips.next();
962 + subnetId = fixip.subnetId();
963 + gwIp = subnetService.getSubnet(subnetId).gatewayIp();
964 + FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp);
965 + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp);
966 + if (gwPort == null) {
967 + gwPort = VtnData.getPort(vPortStore, fixedGwIp);
968 + }
969 + gwMac = gwPort.macAddress();
970 + }
971 + list.add(gwIp);
972 + list.add(gwMac);
973 + return list;
974 + }
975 +
976 + private FixedIp getGwFixedIp(FloatingIp floatingIp) {
977 + RouterId routerId = floatingIp.routerId();
978 + Router router = routerService.getRouter(routerId);
979 + RouterGateway routerGateway = router.externalGatewayInfo();
980 + Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps();
981 + FixedIp fixedGwIp = null;
982 + if (externalFixedIps != null) {
983 + Iterator<FixedIp> exFixedIps = externalFixedIps.iterator();
984 + if (exFixedIps.hasNext()) {
985 + fixedGwIp = exFixedIps.next();
986 + }
987 + }
988 + return fixedGwIp;
989 + }
990 +
991 + private void applyHostMonitoredL3Rules(Host host,
992 + Objective.Operation operation) {
993 + String ifaceId = host.annotations().value(IFACEID);
994 + DeviceId deviceId = host.location().deviceId();
995 + VirtualPortId portId = VirtualPortId.portId(ifaceId);
996 + VirtualPort port = virtualPortService.getPort(portId);
997 + if (port == null) {
998 + port = VtnData.getPort(vPortStore, portId);
999 + }
1000 + TenantId tenantId = port.tenantId();
1001 + Port exPort = exPortOfDevice.get(deviceId);
1002 + SegmentationId l3vni = vtnRscService.getL3vni(tenantId);
1003 + Iterator<FixedIp> fixips = port.fixedIps().iterator();
1004 + SubnetId sid = null;
1005 + IpAddress hostIp = null;
1006 + if (fixips.hasNext()) {
1007 + FixedIp fixip = fixips.next();
1008 + sid = fixip.subnetId();
1009 + hostIp = fixip.ip();
1010 + }
1011 + final SubnetId subnetId = sid;
1012 + // L3 internal network access to each other
1013 + Iterable<RouterInterface> interfaces = routerInterfaceService
1014 + .getRouterInterfaces();
1015 + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces)
1016 + .stream().filter(r -> r.tenantId().equals(tenantId))
1017 + .collect(Collectors.toSet());
1018 + long count = interfacesSet.stream()
1019 + .filter(r -> !r.subnetId().equals(subnetId)).count();
1020 + if (count > 0) {
1021 + if (operation == Objective.Operation.ADD) {
1022 + if (routerInfFlagOfTenant.get(tenantId) != null) {
1023 + applyEastWestL3Flows(host, l3vni, operation);
1024 + } else {
1025 + if (interfacesSet.size() > 1) {
1026 + programInterfacesSet(interfacesSet, operation);
1027 + }
1028 + }
1029 + } else if (operation == Objective.Operation.REMOVE) {
1030 + if (routerInfFlagOfTenant.get(tenantId) != null) {
1031 + applyEastWestL3Flows(host, l3vni, operation);
1032 + }
1033 + }
1034 + }
1035 + // L3 external and internal network access to each other
1036 + FloatingIp floatingIp = null;
1037 + Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps();
1038 + Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream()
1039 + .filter(f -> f.tenantId().equals(tenantId))
1040 + .collect(Collectors.toSet());
1041 + for (FloatingIp f : floatingIpSet) {
1042 + IpAddress fixedIp = f.fixedIp();
1043 + if (fixedIp.equals(hostIp)) {
1044 + floatingIp = f;
1045 + break;
1046 + }
1047 + }
1048 + if (floatingIp != null) {
1049 + VirtualPort fipPort = virtualPortService
1050 + .getPort(floatingIp.networkId(), floatingIp.floatingIp());
1051 + if (fipPort == null) {
1052 + fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(),
1053 + floatingIp.floatingIp());
1054 + }
1055 + applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp,
1056 + l3vni, exPort, operation);
1057 + }
1058 + }
585 } 1059 }
......
...@@ -17,12 +17,20 @@ package org.onosproject.vtn.util; ...@@ -17,12 +17,20 @@ package org.onosproject.vtn.util;
17 17
18 import java.util.ArrayList; 18 import java.util.ArrayList;
19 import java.util.Collection; 19 import java.util.Collection;
20 +import java.util.Iterator;
21 +import java.util.List;
20 22
23 +import org.onlab.packet.IpAddress;
21 import org.onosproject.net.AnnotationKeys; 24 import org.onosproject.net.AnnotationKeys;
22 import org.onosproject.net.Device; 25 import org.onosproject.net.Device;
23 import org.onosproject.net.DeviceId; 26 import org.onosproject.net.DeviceId;
24 import org.onosproject.net.Port; 27 import org.onosproject.net.Port;
25 import org.onosproject.net.PortNumber; 28 import org.onosproject.net.PortNumber;
29 +import org.onosproject.store.service.EventuallyConsistentMap;
30 +import org.onosproject.vtnrsc.FixedIp;
31 +import org.onosproject.vtnrsc.TenantNetworkId;
32 +import org.onosproject.vtnrsc.VirtualPort;
33 +import org.onosproject.vtnrsc.VirtualPortId;
26 import org.slf4j.Logger; 34 import org.slf4j.Logger;
27 import org.slf4j.LoggerFactory; 35 import org.slf4j.LoggerFactory;
28 36
...@@ -94,4 +102,78 @@ public final class VtnData { ...@@ -94,4 +102,78 @@ public final class VtnData {
94 return localTunnelPorts; 102 return localTunnelPorts;
95 } 103 }
96 104
105 + /**
106 + * Get VirtualPort.
107 + *
108 + * @param vPortStore EventuallyConsistentMap of VirtualPort
109 + * @param vPortId VirtualPortId of the VirtualPort
110 + * @return VirtualPort
111 + */
112 + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
113 + VirtualPortId vPortId) {
114 + if (vPortStore != null) {
115 + return vPortStore.get(vPortId);
116 + }
117 + return null;
118 + }
119 +
120 + /**
121 + * Get VirtualPort.
122 + *
123 + * @param vPortStore EventuallyConsistentMap of VirtualPort
124 + * @param fixedIP FixedIp of the VirtualPort
125 + * @return VirtualPort
126 + */
127 + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
128 + FixedIp fixedIP) {
129 + if (vPortStore != null) {
130 + List<VirtualPort> vPorts = new ArrayList<>();
131 + vPortStore.values().stream().forEach(p -> {
132 + Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
133 + while (fixedIps.hasNext()) {
134 + if (fixedIps.next().equals(fixedIP)) {
135 + vPorts.add(p);
136 + break;
137 + }
138 + }
139 + });
140 + if (vPorts.size() == 0) {
141 + return null;
142 + }
143 + return vPorts.get(0);
144 + }
145 + return null;
146 + }
147 +
148 + /**
149 + * Get VirtualPort.
150 + *
151 + * @param vPortStore EventuallyConsistentMap of VirtualPort
152 + * @param networkId TenantNetworkId of the VirtualPort
153 + * @param ip IpAddress of the VirtualPort
154 + * @return VirtualPort
155 + */
156 + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore,
157 + TenantNetworkId networkId, IpAddress ip) {
158 + if (vPortStore != null) {
159 + List<VirtualPort> vPorts = new ArrayList<>();
160 + vPortStore.values().stream()
161 + .filter(p -> p.networkId().equals(networkId))
162 + .forEach(p -> {
163 + Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
164 + while (fixedIps.hasNext()) {
165 + if (fixedIps.next().ip().equals(ip)) {
166 + vPorts.add(p);
167 + break;
168 + }
169 + }
170 + });
171 + if (vPorts.size() == 0) {
172 + return null;
173 + }
174 + return vPorts.get(0);
175 + }
176 + return null;
177 + }
178 +
97 } 179 }
......
...@@ -17,6 +17,7 @@ package org.onosproject.vtnrsc.virtualport; ...@@ -17,6 +17,7 @@ package org.onosproject.vtnrsc.virtualport;
17 17
18 import java.util.Collection; 18 import java.util.Collection;
19 19
20 +import org.onlab.packet.IpAddress;
20 import org.onosproject.net.DeviceId; 21 import org.onosproject.net.DeviceId;
21 import org.onosproject.vtnrsc.FixedIp; 22 import org.onosproject.vtnrsc.FixedIp;
22 import org.onosproject.vtnrsc.TenantId; 23 import org.onosproject.vtnrsc.TenantId;
...@@ -53,6 +54,15 @@ public interface VirtualPortService { ...@@ -53,6 +54,15 @@ public interface VirtualPortService {
53 VirtualPort getPort(FixedIp fixedIP); 54 VirtualPort getPort(FixedIp fixedIP);
54 55
55 /** 56 /**
57 + * Returns the virtualPort associated with the networkId and ip.
58 + *
59 + * @param networkId the TenantNetworkId identifier
60 + * @param ip the ip identifier
61 + * @return virtualPort.
62 + */
63 + VirtualPort getPort(TenantNetworkId networkId, IpAddress ip);
64 +
65 + /**
56 * Returns the collection of the currently known virtualPort. 66 * Returns the collection of the currently known virtualPort.
57 * @return collection of VirtualPort. 67 * @return collection of VirtualPort.
58 */ 68 */
......
...@@ -72,6 +72,7 @@ public class VirtualPortManager implements VirtualPortService { ...@@ -72,6 +72,7 @@ public class VirtualPortManager implements VirtualPortService {
72 private static final String NETWORKID_NOT_NULL = "NetworkId cannot be null"; 72 private static final String NETWORKID_NOT_NULL = "NetworkId cannot be null";
73 private static final String DEVICEID_NOT_NULL = "DeviceId cannot be null"; 73 private static final String DEVICEID_NOT_NULL = "DeviceId cannot be null";
74 private static final String FIXEDIP_NOT_NULL = "FixedIp cannot be null"; 74 private static final String FIXEDIP_NOT_NULL = "FixedIp cannot be null";
75 + private static final String IP_NOT_NULL = "Ip cannot be null";
75 76
76 protected Map<VirtualPortId, VirtualPort> vPortStore; 77 protected Map<VirtualPortId, VirtualPort> vPortStore;
77 protected ApplicationId appId; 78 protected ApplicationId appId;
...@@ -148,6 +149,27 @@ public class VirtualPortManager implements VirtualPortService { ...@@ -148,6 +149,27 @@ public class VirtualPortManager implements VirtualPortService {
148 } 149 }
149 150
150 @Override 151 @Override
152 + public VirtualPort getPort(TenantNetworkId networkId, IpAddress ip) {
153 + checkNotNull(networkId, NETWORKID_NOT_NULL);
154 + checkNotNull(ip, IP_NOT_NULL);
155 + List<VirtualPort> vPorts = new ArrayList<>();
156 + vPortStore.values().stream().filter(p -> p.networkId().equals(networkId))
157 + .forEach(p -> {
158 + Iterator<FixedIp> fixedIps = p.fixedIps().iterator();
159 + while (fixedIps.hasNext()) {
160 + if (fixedIps.next().ip().equals(ip)) {
161 + vPorts.add(p);
162 + break;
163 + }
164 + }
165 + });
166 + if (vPorts.size() == 0) {
167 + return null;
168 + }
169 + return vPorts.get(0);
170 + }
171 +
172 + @Override
151 public Collection<VirtualPort> getPorts() { 173 public Collection<VirtualPort> getPorts() {
152 return Collections.unmodifiableCollection(vPortStore.values()); 174 return Collections.unmodifiableCollection(vPortStore.values());
153 } 175 }
......