diff options
author | Ashlee Young <ashlee@wildernessvoice.com> | 2015-12-06 07:15:03 -0800 |
---|---|---|
committer | Ashlee Young <ashlee@wildernessvoice.com> | 2015-12-08 10:55:21 -0800 |
commit | 76dc892491948adae5e5e62cf94448967e8d865b (patch) | |
tree | 7a33ef05cc583946db21edad627060f280a53549 /framework/src/onos/apps/vtn/vtnmgr | |
parent | d333c63fdec8b064184b0a26f8d777f267577fde (diff) |
Fixes bad POM file with ONOS commit 8c68536972f63069c263635c9d9f4f31d7f3e9a2
Change-Id: I7adb5a2d3738d53dbc41db7577768b0e7ced5450
Signed-off-by: Ashlee Young <ashlee@wildernessvoice.com>
Diffstat (limited to 'framework/src/onos/apps/vtn/vtnmgr')
5 files changed, 704 insertions, 2 deletions
diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java index a104e529..d7ee3607 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/VTNService.java @@ -17,6 +17,7 @@ package org.onosproject.vtn.manager; import org.onosproject.net.Device; import org.onosproject.net.Host; +import org.onosproject.vtnrsc.event.VtnRscEventFeedback; /** * VTN application that applies configuration and flows to the device. @@ -67,4 +68,32 @@ public interface VTNService { */ void onHostVanished(Host host); + /** + * Applies east west flows when neutron created router interface. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback); + + /** + * Remove east west flows when neutron removed router interface. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback); + + /** + * Applies north south flows when neutron bind floating ip. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onFloatingIpDetected(VtnRscEventFeedback l3Feedback); + + /** + * Applies north south flows when neutron unbind floating ip. + * + * @param l3Feedback VtnrscEventFeedback + */ + void onFloatingIpVanished(VtnRscEventFeedback l3Feedback); + } diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java index be6b9364..6429314e 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/manager/impl/VTNManager.java @@ -18,6 +18,7 @@ package org.onosproject.vtn.manager.impl; import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.NICIRA_SET_TUNNEL_DST; import static org.slf4j.LoggerFactory.getLogger; +import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -25,6 +26,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.stream.Collectors; import org.apache.felix.scr.annotations.Activate; import org.apache.felix.scr.annotations.Component; @@ -39,9 +41,11 @@ import org.onlab.util.KryoNamespace; import org.onosproject.core.ApplicationId; import org.onosproject.core.CoreService; import org.onosproject.mastership.MastershipService; +import org.onosproject.net.AnnotationKeys; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Host; +import org.onosproject.net.HostId; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; import org.onosproject.net.behaviour.BridgeConfig; @@ -74,8 +78,12 @@ import org.onosproject.store.service.EventuallyConsistentMap; import org.onosproject.store.service.LogicalClockService; import org.onosproject.store.service.StorageService; import org.onosproject.vtn.manager.VTNService; +import org.onosproject.vtn.table.ArpService; import org.onosproject.vtn.table.ClassifierService; +import org.onosproject.vtn.table.DnatService; import org.onosproject.vtn.table.L2ForwardService; +import org.onosproject.vtn.table.L3ForwardService; +import org.onosproject.vtn.table.SnatService; import org.onosproject.vtn.table.impl.ClassifierServiceImpl; import org.onosproject.vtn.table.impl.L2ForwardServiceImpl; import org.onosproject.vtn.util.DataPathIdGenerator; @@ -85,6 +93,11 @@ import org.onosproject.vtnrsc.AllowedAddressPair; import org.onosproject.vtnrsc.BindingHostId; import org.onosproject.vtnrsc.DefaultVirtualPort; import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.FloatingIp; +import org.onosproject.vtnrsc.Router; +import org.onosproject.vtnrsc.RouterGateway; +import org.onosproject.vtnrsc.RouterId; +import org.onosproject.vtnrsc.RouterInterface; import org.onosproject.vtnrsc.SecurityGroup; import org.onosproject.vtnrsc.SegmentationId; import org.onosproject.vtnrsc.SubnetId; @@ -93,6 +106,14 @@ import org.onosproject.vtnrsc.TenantNetwork; import org.onosproject.vtnrsc.TenantNetworkId; import org.onosproject.vtnrsc.VirtualPort; import org.onosproject.vtnrsc.VirtualPortId; +import org.onosproject.vtnrsc.event.VtnRscEvent; +import org.onosproject.vtnrsc.event.VtnRscEventFeedback; +import org.onosproject.vtnrsc.event.VtnRscListener; +import org.onosproject.vtnrsc.floatingip.FloatingIpService; +import org.onosproject.vtnrsc.router.RouterService; +import org.onosproject.vtnrsc.routerinterface.RouterInterfaceService; +import org.onosproject.vtnrsc.service.VtnRscService; +import org.onosproject.vtnrsc.subnet.SubnetService; import org.onosproject.vtnrsc.tenantnetwork.TenantNetworkService; import org.onosproject.vtnrsc.virtualport.VirtualPortService; import org.slf4j.Logger; @@ -142,12 +163,32 @@ public class VTNManager implements VTNService { @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) protected GroupService groupService; + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected SubnetService subnetService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected VtnRscService vtnRscService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected FloatingIpService floatingIpService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterService routerService; + + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) + protected RouterInterfaceService routerInterfaceService; + private ApplicationId appId; private ClassifierService classifierService; private L2ForwardService l2ForwardService; + private ArpService arpService; + private L3ForwardService l3ForwardService; + private SnatService snatService; + private DnatService dnatService; private final HostListener hostListener = new InnerHostListener(); private final DeviceListener deviceListener = new InnerDeviceListener(); + private final VtnRscListener l3EventListener = new VtnL3EventListener(); private static final String IFACEID = "ifaceid"; private static final String CONTROLLER_IP_KEY = "ipaddress"; @@ -156,11 +197,19 @@ public class VTNManager implements VTNService { private static final String VIRTUALPORT = "vtn-virtual-port"; private static final String SWITCHES_OF_CONTROLLER = "switchesOfController"; private static final String SWITCH_OF_LOCAL_HOST_PORTS = "switchOfLocalHostPorts"; + private static final String ROUTERINF_FLAG_OF_TENANT = "routerInfFlagOfTenant"; + private static final String HOSTS_OF_SUBNET = "hostsOfSubnet"; + private static final String EX_PORT_OF_DEVICE = "exPortOfDevice"; private static final String DEFAULT_IP = "0.0.0.0"; + private static final String PORT_MAC = "portMac"; + private static final int SUBNET_NUM = 2; private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore; private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController; private EventuallyConsistentMap<DeviceId, NetworkOfLocalHostPorts> switchOfLocalHostPorts; + private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet; + private EventuallyConsistentMap<TenantId, Boolean> routerInfFlagOfTenant; + private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice; @Activate public void activate() { @@ -206,6 +255,24 @@ public class VTNManager implements VTNService { .withTimestampProvider((k, v) -> clockService.getTimestamp()) .build(); + hostsOfSubnet = storageService + .<SubnetId, Map<HostId, Host>>eventuallyConsistentMapBuilder() + .withName(HOSTS_OF_SUBNET).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + routerInfFlagOfTenant = storageService + .<TenantId, Boolean>eventuallyConsistentMapBuilder() + .withName(ROUTERINF_FLAG_OF_TENANT).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + + exPortOfDevice = storageService + .<DeviceId, Port>eventuallyConsistentMapBuilder() + .withName(EX_PORT_OF_DEVICE).withSerializer(serializer) + .withTimestampProvider((k, v) -> clockService.getTimestamp()) + .build(); + log.info("Started"); } @@ -213,6 +280,7 @@ public class VTNManager implements VTNService { public void deactivate() { deviceService.removeListener(deviceListener); hostService.removeListener(hostListener); + vtnRscService.removeListener(l3EventListener); log.info("Stopped"); } @@ -278,14 +346,36 @@ public class VTNManager implements VTNService { @Override public void onHostDetected(Host host) { + DeviceId deviceId = host.location().deviceId(); + if (!mastershipService.isLocalMaster(deviceId)) { + return; + } + String ifaceId = host.annotations().value(IFACEID); + if (ifaceId == null) { + log.error("The ifaceId of Host is null"); + return; + } // apply L2 openflow rules applyHostMonitoredL2Rules(host, Objective.Operation.ADD); + // apply L3 openflow rules + applyHostMonitoredL3Rules(host, Objective.Operation.ADD); } @Override public void onHostVanished(Host host) { + DeviceId deviceId = host.location().deviceId(); + if (!mastershipService.isLocalMaster(deviceId)) { + return; + } + String ifaceId = host.annotations().value(IFACEID); + if (ifaceId == null) { + log.error("The ifaceId of Host is null"); + return; + } // apply L2 openflow rules applyHostMonitoredL2Rules(host, Objective.Operation.REMOVE); + // apply L3 openflow rules + applyHostMonitoredL3Rules(host, Objective.Operation.REMOVE); } private void programTunnelConfig(DeviceId localDeviceId, IpAddress localIp, @@ -376,7 +466,7 @@ public class VTNManager implements VTNService { VirtualPortId virtualPortId = VirtualPortId.portId(ifaceId); VirtualPort virtualPort = virtualPortService.getPort(virtualPortId); if (virtualPort == null) { - virtualPort = vPortStore.get(virtualPortId); + virtualPort = VtnData.getPort(vPortStore, virtualPortId); } Iterable<Device> devices = deviceService.getAvailableDevices(); @@ -582,4 +672,388 @@ public class VTNManager implements VTNService { appid); groupService.addGroup(groupDescription); } + + private class VtnL3EventListener implements VtnRscListener { + @Override + public void event(VtnRscEvent event) { + VtnRscEventFeedback l3Feedback = event.subject(); + if (VtnRscEvent.Type.ROUTER_INTERFACE_PUT == event.type()) { + onRouterInterfaceDetected(l3Feedback); + } else + if (VtnRscEvent.Type.ROUTER_INTERFACE_DELETE == event.type()) { + onRouterInterfaceVanished(l3Feedback); + } else if (VtnRscEvent.Type.FLOATINGIP_PUT == event.type()) { + onFloatingIpDetected(l3Feedback); + } else if (VtnRscEvent.Type.FLOATINGIP_DELETE == event.type()) { + onFloatingIpVanished(l3Feedback); + } + } + + } + + @Override + public void onRouterInterfaceDetected(VtnRscEventFeedback l3Feedback) { + Objective.Operation operation = Objective.Operation.ADD; + RouterInterface routerInf = l3Feedback.routerInterface(); + Iterable<RouterInterface> interfaces = routerInterfaceService + .getRouterInterfaces(); + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces) + .stream().filter(r -> r.tenantId().equals(routerInf.tenantId())) + .collect(Collectors.toSet()); + if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) { + programRouterInterface(routerInf, operation); + } else { + if (interfacesSet.size() >= SUBNET_NUM) { + programInterfacesSet(interfacesSet, operation); + } + } + } + + @Override + public void onRouterInterfaceVanished(VtnRscEventFeedback l3Feedback) { + Objective.Operation operation = Objective.Operation.REMOVE; + RouterInterface routerInf = l3Feedback.routerInterface(); + Iterable<RouterInterface> interfaces = routerInterfaceService + .getRouterInterfaces(); + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces) + .stream().filter(r -> r.tenantId().equals(routerInf.tenantId())) + .collect(Collectors.toSet()); + if (routerInfFlagOfTenant.get(routerInf.tenantId()) != null) { + programRouterInterface(routerInf, operation); + if (interfacesSet.size() == 1) { + routerInfFlagOfTenant.remove(routerInf.tenantId()); + interfacesSet.stream().forEach(r -> { + programRouterInterface(r, operation); + }); + } + } + } + + @Override + public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) { + programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_PUT); + } + + @Override + public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) { + programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_DELETE); + } + + private void programInterfacesSet(Set<RouterInterface> interfacesSet, + Objective.Operation operation) { + int subnetVmNum = 0; + for (RouterInterface r : interfacesSet) { + // Get all the host of the subnet + Map<HostId, Host> hosts = hostsOfSubnet.get(r.subnetId()); + if (hosts.size() > 0) { + subnetVmNum++; + if (subnetVmNum >= SUBNET_NUM) { + routerInfFlagOfTenant.put(r.tenantId(), true); + interfacesSet.stream().forEach(f -> { + programRouterInterface(f, operation); + }); + break; + } + } + } + } + + private void programRouterInterface(RouterInterface routerInf, + Objective.Operation operation) { + SegmentationId l3vni = vtnRscService.getL3vni(routerInf.tenantId()); + // Get all the host of the subnet + Map<HostId, Host> hosts = hostsOfSubnet.get(routerInf.subnetId()); + hosts.values().stream().forEach(h -> { + applyEastWestL3Flows(h, l3vni, operation); + }); + } + + private void applyEastWestL3Flows(Host h, SegmentationId l3vni, + Objective.Operation operation) { + if (!mastershipService.isLocalMaster(h.location().deviceId())) { + log.debug("not master device:{}", h.location().deviceId()); + return; + } + String ifaceId = h.annotations().value(IFACEID); + VirtualPort hPort = virtualPortService + .getPort(VirtualPortId.portId(ifaceId)); + if (hPort == null) { + hPort = VtnData.getPort(vPortStore, VirtualPortId.portId(ifaceId)); + } + IpAddress srcIp = null; + IpAddress srcGwIp = null; + MacAddress srcVmGwMac = null; + SubnetId srcSubnetId = null; + Iterator<FixedIp> srcIps = hPort.fixedIps().iterator(); + if (srcIps.hasNext()) { + FixedIp fixedIp = srcIps.next(); + srcIp = fixedIp.ip(); + srcSubnetId = fixedIp.subnetId(); + srcGwIp = subnetService.getSubnet(srcSubnetId).gatewayIp(); + FixedIp fixedGwIp = FixedIp.fixedIp(srcSubnetId, srcGwIp); + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp); + if (gwPort == null) { + gwPort = VtnData.getPort(vPortStore, fixedGwIp); + } + srcVmGwMac = gwPort.macAddress(); + } + TenantNetwork network = tenantNetworkService + .getNetwork(hPort.networkId()); + // Classifier rules + classifierService + .programL3InPortClassifierRules(h.location().deviceId(), + h.location().port(), h.mac(), + srcVmGwMac, l3vni, operation); + // Arp rules + if (operation == Objective.Operation.ADD) { + classifierService.programArpClassifierRules(h.location().deviceId(), + srcGwIp, + network.segmentationId(), + operation); + DriverHandler handler = driverService.createHandler(h.location().deviceId()); + arpService.programArpRules(handler, h.location().deviceId(), srcGwIp, + network.segmentationId(), srcVmGwMac, + operation); + } + Iterable<Device> devices = deviceService.getAvailableDevices(); + IpAddress srcArpIp = srcIp; + MacAddress srcArpGwMac = srcVmGwMac; + Sets.newHashSet(devices).stream() + .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> { + // L3FWD rules + l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp, + network.segmentationId(), + srcArpGwMac, h.mac(), + operation); + }); + } + + private void programFloatingIpEvent(VtnRscEventFeedback l3Feedback, + VtnRscEvent.Type type) { + FloatingIp floaingIp = l3Feedback.floatingIp(); + if (floaingIp != null) { + VirtualPortId vmPortId = floaingIp.portId(); + VirtualPort vmPort = virtualPortService.getPort(vmPortId); + VirtualPort fipPort = virtualPortService + .getPort(floaingIp.networkId(), floaingIp.floatingIp()); + if (vmPort == null) { + vmPort = VtnData.getPort(vPortStore, vmPortId); + } + if (fipPort == null) { + fipPort = VtnData.getPort(vPortStore, floaingIp.networkId(), + floaingIp.floatingIp()); + } + Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress()); + Host host = null; + for (Host h : hostSet) { + String ifaceid = h.annotations().value(IFACEID); + if (ifaceid != null && ifaceid.equals(vmPortId.portId())) { + host = h; + break; + } + } + if (host != null && vmPort != null && fipPort != null) { + DeviceId deviceId = host.location().deviceId(); + Port exPort = exPortOfDevice.get(deviceId); + SegmentationId l3vni = vtnRscService + .getL3vni(vmPort.tenantId()); + // Floating ip BIND + if (type == VtnRscEvent.Type.FLOATINGIP_PUT) { + applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort, + floaingIp, l3vni, exPort, + Objective.Operation.ADD); + } else if (type == VtnRscEvent.Type.FLOATINGIP_DELETE) { + // Floating ip UNBIND + applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort, + floaingIp, l3vni, exPort, + Objective.Operation.REMOVE); + } + } + } + } + + private void applyNorthSouthL3Flows(DeviceId deviceId, Host host, + VirtualPort vmPort, VirtualPort fipPort, + FloatingIp floatingIp, + SegmentationId l3Vni, Port exPort, + Objective.Operation operation) { + if (!mastershipService.isLocalMaster(deviceId)) { + log.debug("not master device:{}", deviceId); + return; + } + List gwIpMac = getGwIpAndMac(vmPort); + IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0); + MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1); + FixedIp fixedGwIp = getGwFixedIp(floatingIp); + MacAddress fGwMac = null; + if (fixedGwIp != null) { + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp); + if (gwPort == null) { + gwPort = VtnData.getPort(vPortStore, fixedGwIp); + } + fGwMac = gwPort.macAddress(); + } + TenantNetwork vmNetwork = tenantNetworkService + .getNetwork(vmPort.networkId()); + TenantNetwork fipNetwork = tenantNetworkService + .getNetwork(fipPort.networkId()); + // L3 downlink traffic flow + MacAddress exPortMac = MacAddress.valueOf(exPort.annotations().value(PORT_MAC)); + classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(), + fipNetwork.segmentationId(), + operation); + classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(), + floatingIp.floatingIp(), operation); + DriverHandler handler = driverService.createHandler(deviceId); + arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(), + fipNetwork.segmentationId(), exPortMac, + operation); + dnatService.programRules(deviceId, floatingIp.floatingIp(), + fGwMac, floatingIp.fixedIp(), + l3Vni, operation); + l3ForwardService + .programRouteRules(deviceId, l3Vni, floatingIp.fixedIp(), + vmNetwork.segmentationId(), dstVmGwMac, + vmPort.macAddress(), operation); + + // L3 uplink traffic flow + classifierService.programL3InPortClassifierRules(deviceId, + host.location().port(), + host.mac(), dstVmGwMac, + l3Vni, operation); + snatService.programRules(deviceId, l3Vni, floatingIp.fixedIp(), + fGwMac, exPortMac, + floatingIp.floatingIp(), + fipNetwork.segmentationId(), operation); + if (operation == Objective.Operation.ADD) { + classifierService.programArpClassifierRules(deviceId, dstVmGwIp, + vmNetwork.segmentationId(), + operation); + arpService.programArpRules(handler, deviceId, dstVmGwIp, + vmNetwork.segmentationId(), dstVmGwMac, + operation); + l2ForwardService.programLocalOut(deviceId, + fipNetwork.segmentationId(), + exPort.number(), fGwMac, operation); + } + } + + private Port getExPort(DeviceId deviceId) { + List<Port> ports = deviceService.getPorts(deviceId); + Port exPort = null; + for (Port port : ports) { + String portName = port.annotations().value(AnnotationKeys.PORT_NAME); + if (portName != null && portName.equals(EX_PORT_NAME)) { + exPort = port; + break; + } + } + return exPort; + } + + private List getGwIpAndMac(VirtualPort port) { + List list = new ArrayList(); + MacAddress gwMac = null; + SubnetId subnetId = null; + IpAddress gwIp = null; + Iterator<FixedIp> fixips = port.fixedIps().iterator(); + if (fixips.hasNext()) { + FixedIp fixip = fixips.next(); + subnetId = fixip.subnetId(); + gwIp = subnetService.getSubnet(subnetId).gatewayIp(); + FixedIp fixedGwIp = FixedIp.fixedIp(fixip.subnetId(), gwIp); + VirtualPort gwPort = virtualPortService.getPort(fixedGwIp); + if (gwPort == null) { + gwPort = VtnData.getPort(vPortStore, fixedGwIp); + } + gwMac = gwPort.macAddress(); + } + list.add(gwIp); + list.add(gwMac); + return list; + } + + private FixedIp getGwFixedIp(FloatingIp floatingIp) { + RouterId routerId = floatingIp.routerId(); + Router router = routerService.getRouter(routerId); + RouterGateway routerGateway = router.externalGatewayInfo(); + Iterable<FixedIp> externalFixedIps = routerGateway.externalFixedIps(); + FixedIp fixedGwIp = null; + if (externalFixedIps != null) { + Iterator<FixedIp> exFixedIps = externalFixedIps.iterator(); + if (exFixedIps.hasNext()) { + fixedGwIp = exFixedIps.next(); + } + } + return fixedGwIp; + } + + private void applyHostMonitoredL3Rules(Host host, + Objective.Operation operation) { + String ifaceId = host.annotations().value(IFACEID); + DeviceId deviceId = host.location().deviceId(); + VirtualPortId portId = VirtualPortId.portId(ifaceId); + VirtualPort port = virtualPortService.getPort(portId); + if (port == null) { + port = VtnData.getPort(vPortStore, portId); + } + TenantId tenantId = port.tenantId(); + Port exPort = exPortOfDevice.get(deviceId); + SegmentationId l3vni = vtnRscService.getL3vni(tenantId); + Iterator<FixedIp> fixips = port.fixedIps().iterator(); + SubnetId sid = null; + IpAddress hostIp = null; + if (fixips.hasNext()) { + FixedIp fixip = fixips.next(); + sid = fixip.subnetId(); + hostIp = fixip.ip(); + } + final SubnetId subnetId = sid; + // L3 internal network access to each other + Iterable<RouterInterface> interfaces = routerInterfaceService + .getRouterInterfaces(); + Set<RouterInterface> interfacesSet = Sets.newHashSet(interfaces) + .stream().filter(r -> r.tenantId().equals(tenantId)) + .collect(Collectors.toSet()); + long count = interfacesSet.stream() + .filter(r -> !r.subnetId().equals(subnetId)).count(); + if (count > 0) { + if (operation == Objective.Operation.ADD) { + if (routerInfFlagOfTenant.get(tenantId) != null) { + applyEastWestL3Flows(host, l3vni, operation); + } else { + if (interfacesSet.size() > 1) { + programInterfacesSet(interfacesSet, operation); + } + } + } else if (operation == Objective.Operation.REMOVE) { + if (routerInfFlagOfTenant.get(tenantId) != null) { + applyEastWestL3Flows(host, l3vni, operation); + } + } + } + // L3 external and internal network access to each other + FloatingIp floatingIp = null; + Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps(); + Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream() + .filter(f -> f.tenantId().equals(tenantId)) + .collect(Collectors.toSet()); + for (FloatingIp f : floatingIpSet) { + IpAddress fixedIp = f.fixedIp(); + if (fixedIp.equals(hostIp)) { + floatingIp = f; + break; + } + } + if (floatingIp != null) { + VirtualPort fipPort = virtualPortService + .getPort(floatingIp.networkId(), floatingIp.floatingIp()); + if (fipPort == null) { + fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(), + floatingIp.floatingIp()); + } + applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp, + l3vni, exPort, operation); + } + } } diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java index b548938b..ebb9ac3b 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/ArpService.java @@ -17,10 +17,13 @@ package org.onosproject.vtn.table; import org.onlab.packet.IpAddress; import org.onlab.packet.MacAddress; + import org.onosproject.net.DeviceId; +import org.onosproject.net.driver.DriverHandler; import org.onosproject.net.flowobjective.Objective; import org.onosproject.vtnrsc.SegmentationId; + /** * ArpService interface providing the rules in ARP table which is Table(10). */ @@ -32,13 +35,14 @@ public interface ArpService { * Action: set arp_operation, move arp_eth_src to arp_eth_dst, set arp_eth_src, * move arp_ip_src to arp_ip_dst, set arp_ip_src, set output port. * + * @param hander DriverHandler * @param deviceId Device Id * @param dstIP destination ip * @param matchVni the vni of the source network (l2vni) * @param dstMac destination mac * @param type the operation type of the flow rules */ - void programArpRules(DeviceId deviceId, IpAddress dstIP, + void programArpRules(DriverHandler hander, DeviceId deviceId, IpAddress dstIP, SegmentationId matchVni, MacAddress dstMac, Objective.Operation type); } diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java new file mode 100644 index 00000000..574d15a7 --- /dev/null +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/table/impl/ArpServiceImpl.java @@ -0,0 +1,113 @@ +/* + * Copyright 2015 Open Networking Laboratory + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onosproject.vtn.table.impl; + +import static com.google.common.base.Preconditions.checkNotNull; +import static org.slf4j.LoggerFactory.getLogger; + +import org.onlab.osgi.DefaultServiceDirectory; +import org.onlab.osgi.ServiceDirectory; +import org.onlab.packet.EthType.EtherType; +import org.onlab.packet.Ip4Address; +import org.onlab.packet.IpAddress; +import org.onlab.packet.MacAddress; +import org.onosproject.core.ApplicationId; +import org.onosproject.net.DeviceId; +import org.onosproject.net.PortNumber; +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; +import org.onosproject.net.driver.DriverHandler; +import org.onosproject.net.flow.DefaultTrafficSelector; +import org.onosproject.net.flow.DefaultTrafficTreatment; +import org.onosproject.net.flow.TrafficSelector; +import org.onosproject.net.flow.TrafficTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatment; +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; +import org.onosproject.net.flowobjective.DefaultForwardingObjective; +import org.onosproject.net.flowobjective.FlowObjectiveService; +import org.onosproject.net.flowobjective.ForwardingObjective; +import org.onosproject.net.flowobjective.ForwardingObjective.Flag; +import org.onosproject.net.flowobjective.Objective; +import org.onosproject.net.flowobjective.Objective.Operation; +import org.onosproject.vtn.table.ArpService; +import org.onosproject.vtnrsc.SegmentationId; +import org.slf4j.Logger; + +/** + * ArpTable class providing the rules in ARP table. + */ +public class ArpServiceImpl implements ArpService { + private final Logger log = getLogger(getClass()); + + private static final int ARP_PRIORITY = 0xffff; + private static final short ARP_RESPONSE = 0x2; + private static final EtherType ARP_TYPE = EtherType.ARP; + + private final FlowObjectiveService flowObjectiveService; + private final ApplicationId appId; + + /** + * Construct a ArpServiceImpl object. + * + * @param appId the application id of vtn + */ + public ArpServiceImpl(ApplicationId appId) { + this.appId = checkNotNull(appId, "ApplicationId can not be null"); + ServiceDirectory serviceDirectory = new DefaultServiceDirectory(); + this.flowObjectiveService = serviceDirectory.get(FlowObjectiveService.class); + } + + @Override + public void programArpRules(DriverHandler hander, DeviceId deviceId, + IpAddress dstIP, SegmentationId srcVni, + MacAddress dstMac, Operation type) { + TrafficSelector selector = DefaultTrafficSelector.builder() + .matchEthType(ARP_TYPE.ethType().toShort()) + .matchArpTpa(Ip4Address.valueOf(dstIP.toString())) + .matchTunnelId(Long.parseLong(srcVni.segmentationId())).build(); + + ExtensionTreatmentResolver resolver = hander + .behaviour(ExtensionTreatmentResolver.class); + ExtensionTreatment ethSrcToDst = resolver + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes + .NICIRA_MOV_ETH_SRC_TO_DST.type()); + ExtensionTreatment arpShaToTha = resolver + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes + .NICIRA_MOV_ARP_SHA_TO_THA.type()); + ExtensionTreatment arpSpaToTpa = resolver + .getExtensionInstruction(ExtensionTreatmentType.ExtensionTreatmentTypes + .NICIRA_MOV_ARP_SPA_TO_TPA.type()); + TrafficTreatment treatment = DefaultTrafficTreatment.builder() + .extension(ethSrcToDst, deviceId) + .setEthSrc(dstMac).setArpOp(ARP_RESPONSE) + .extension(arpShaToTha, deviceId) + .extension(arpSpaToTpa, deviceId) + .setArpSha(dstMac).setArpSpa(dstIP) + .setOutput(PortNumber.IN_PORT).build(); + + ForwardingObjective.Builder objective = DefaultForwardingObjective + .builder().withTreatment(treatment).withSelector(selector) + .fromApp(appId).withFlag(Flag.SPECIFIC) + .withPriority(ARP_PRIORITY); + + if (type.equals(Objective.Operation.ADD)) { + log.debug("PrivateArpRules-->ADD"); + flowObjectiveService.forward(deviceId, objective.add()); + } else { + log.debug("PrivateArpRules-->REMOVE"); + flowObjectiveService.forward(deviceId, objective.remove()); + } + } +} diff --git a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java index a8562e7f..cca905c2 100644 --- a/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java +++ b/framework/src/onos/apps/vtn/vtnmgr/src/main/java/org/onosproject/vtn/util/VtnData.java @@ -17,12 +17,20 @@ package org.onosproject.vtn.util; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; +import java.util.List; +import org.onlab.packet.IpAddress; import org.onosproject.net.AnnotationKeys; import org.onosproject.net.Device; import org.onosproject.net.DeviceId; import org.onosproject.net.Port; import org.onosproject.net.PortNumber; +import org.onosproject.store.service.EventuallyConsistentMap; +import org.onosproject.vtnrsc.FixedIp; +import org.onosproject.vtnrsc.TenantNetworkId; +import org.onosproject.vtnrsc.VirtualPort; +import org.onosproject.vtnrsc.VirtualPortId; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -94,4 +102,78 @@ public final class VtnData { return localTunnelPorts; } + /** + * Get VirtualPort. + * + * @param vPortStore EventuallyConsistentMap of VirtualPort + * @param vPortId VirtualPortId of the VirtualPort + * @return VirtualPort + */ + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore, + VirtualPortId vPortId) { + if (vPortStore != null) { + return vPortStore.get(vPortId); + } + return null; + } + + /** + * Get VirtualPort. + * + * @param vPortStore EventuallyConsistentMap of VirtualPort + * @param fixedIP FixedIp of the VirtualPort + * @return VirtualPort + */ + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore, + FixedIp fixedIP) { + if (vPortStore != null) { + List<VirtualPort> vPorts = new ArrayList<>(); + vPortStore.values().stream().forEach(p -> { + Iterator<FixedIp> fixedIps = p.fixedIps().iterator(); + while (fixedIps.hasNext()) { + if (fixedIps.next().equals(fixedIP)) { + vPorts.add(p); + break; + } + } + }); + if (vPorts.size() == 0) { + return null; + } + return vPorts.get(0); + } + return null; + } + + /** + * Get VirtualPort. + * + * @param vPortStore EventuallyConsistentMap of VirtualPort + * @param networkId TenantNetworkId of the VirtualPort + * @param ip IpAddress of the VirtualPort + * @return VirtualPort + */ + public static VirtualPort getPort(EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore, + TenantNetworkId networkId, IpAddress ip) { + if (vPortStore != null) { + List<VirtualPort> vPorts = new ArrayList<>(); + vPortStore.values().stream() + .filter(p -> p.networkId().equals(networkId)) + .forEach(p -> { + Iterator<FixedIp> fixedIps = p.fixedIps().iterator(); + while (fixedIps.hasNext()) { + if (fixedIps.next().ip().equals(ip)) { + vPorts.add(p); + break; + } + } + }); + if (vPorts.size() == 0) { + return null; + } + return vPorts.get(0); + } + return null; + } + } |