Bob zhou

[ONOS-4426] Upgrade Vtn Module when access same network segment

Change-Id: Id0d00e9d0e93d1baf4ff20560469316fee5a3186
...@@ -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.nio.ByteBuffer;
21 import java.util.ArrayList; 22 import java.util.ArrayList;
22 import java.util.Arrays; 23 import java.util.Arrays;
23 import java.util.Collection; 24 import java.util.Collection;
...@@ -27,6 +28,7 @@ import java.util.Iterator; ...@@ -27,6 +28,7 @@ import java.util.Iterator;
27 import java.util.List; 28 import java.util.List;
28 import java.util.Map; 29 import java.util.Map;
29 import java.util.Set; 30 import java.util.Set;
31 +import java.util.UUID;
30 import java.util.concurrent.ConcurrentHashMap; 32 import java.util.concurrent.ConcurrentHashMap;
31 import java.util.stream.Collectors; 33 import java.util.stream.Collectors;
32 34
...@@ -36,14 +38,19 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -36,14 +38,19 @@ import org.apache.felix.scr.annotations.Deactivate;
36 import org.apache.felix.scr.annotations.Reference; 38 import org.apache.felix.scr.annotations.Reference;
37 import org.apache.felix.scr.annotations.ReferenceCardinality; 39 import org.apache.felix.scr.annotations.ReferenceCardinality;
38 import org.apache.felix.scr.annotations.Service; 40 import org.apache.felix.scr.annotations.Service;
41 +import org.onlab.packet.ARP;
42 +import org.onlab.packet.Ethernet;
43 +import org.onlab.packet.IPv4;
39 import org.onlab.packet.Ip4Address; 44 import org.onlab.packet.Ip4Address;
40 import org.onlab.packet.IpAddress; 45 import org.onlab.packet.IpAddress;
46 +import org.onlab.packet.IpPrefix;
41 import org.onlab.packet.MacAddress; 47 import org.onlab.packet.MacAddress;
42 import org.onlab.util.KryoNamespace; 48 import org.onlab.util.KryoNamespace;
43 import org.onosproject.core.ApplicationId; 49 import org.onosproject.core.ApplicationId;
44 import org.onosproject.core.CoreService; 50 import org.onosproject.core.CoreService;
45 import org.onosproject.mastership.MastershipService; 51 import org.onosproject.mastership.MastershipService;
46 import org.onosproject.net.AnnotationKeys; 52 import org.onosproject.net.AnnotationKeys;
53 +import org.onosproject.net.ConnectPoint;
47 import org.onosproject.net.Device; 54 import org.onosproject.net.Device;
48 import org.onosproject.net.DeviceId; 55 import org.onosproject.net.DeviceId;
49 import org.onosproject.net.Host; 56 import org.onosproject.net.Host;
...@@ -61,7 +68,12 @@ import org.onosproject.net.device.DeviceService; ...@@ -61,7 +68,12 @@ import org.onosproject.net.device.DeviceService;
61 import org.onosproject.net.driver.DriverHandler; 68 import org.onosproject.net.driver.DriverHandler;
62 import org.onosproject.net.driver.DriverService; 69 import org.onosproject.net.driver.DriverService;
63 import org.onosproject.net.flow.DefaultTrafficTreatment; 70 import org.onosproject.net.flow.DefaultTrafficTreatment;
71 +import org.onosproject.net.flow.FlowEntry;
72 +import org.onosproject.net.flow.FlowRuleService;
73 +import org.onosproject.net.flow.TrafficSelector;
74 +import org.onosproject.net.flow.TrafficTreatment;
64 import org.onosproject.net.flow.TrafficTreatment.Builder; 75 import org.onosproject.net.flow.TrafficTreatment.Builder;
76 +import org.onosproject.net.flow.criteria.Criterion;
65 import org.onosproject.net.flow.instructions.ExtensionTreatment; 77 import org.onosproject.net.flow.instructions.ExtensionTreatment;
66 import org.onosproject.net.flowobjective.Objective; 78 import org.onosproject.net.flowobjective.Objective;
67 import org.onosproject.net.group.DefaultGroupBucket; 79 import org.onosproject.net.group.DefaultGroupBucket;
...@@ -75,6 +87,12 @@ import org.onosproject.net.group.GroupService; ...@@ -75,6 +87,12 @@ import org.onosproject.net.group.GroupService;
75 import org.onosproject.net.host.HostEvent; 87 import org.onosproject.net.host.HostEvent;
76 import org.onosproject.net.host.HostListener; 88 import org.onosproject.net.host.HostListener;
77 import org.onosproject.net.host.HostService; 89 import org.onosproject.net.host.HostService;
90 +import org.onosproject.net.packet.DefaultOutboundPacket;
91 +import org.onosproject.net.packet.InboundPacket;
92 +import org.onosproject.net.packet.OutboundPacket;
93 +import org.onosproject.net.packet.PacketContext;
94 +import org.onosproject.net.packet.PacketProcessor;
95 +import org.onosproject.net.packet.PacketService;
78 import org.onosproject.store.serializers.KryoNamespaces; 96 import org.onosproject.store.serializers.KryoNamespaces;
79 import org.onosproject.store.service.ConsistentMap; 97 import org.onosproject.store.service.ConsistentMap;
80 import org.onosproject.store.service.EventuallyConsistentMap; 98 import org.onosproject.store.service.EventuallyConsistentMap;
...@@ -96,13 +114,16 @@ import org.onosproject.vtn.table.impl.L2ForwardServiceImpl; ...@@ -96,13 +114,16 @@ import org.onosproject.vtn.table.impl.L2ForwardServiceImpl;
96 import org.onosproject.vtn.table.impl.L3ForwardServiceImpl; 114 import org.onosproject.vtn.table.impl.L3ForwardServiceImpl;
97 import org.onosproject.vtn.table.impl.SnatServiceImpl; 115 import org.onosproject.vtn.table.impl.SnatServiceImpl;
98 import org.onosproject.vtn.util.DataPathIdGenerator; 116 import org.onosproject.vtn.util.DataPathIdGenerator;
117 +import org.onosproject.vtn.util.IpUtil;
99 import org.onosproject.vtn.util.VtnConfig; 118 import org.onosproject.vtn.util.VtnConfig;
100 import org.onosproject.vtn.util.VtnData; 119 import org.onosproject.vtn.util.VtnData;
101 import org.onosproject.vtnrsc.AllowedAddressPair; 120 import org.onosproject.vtnrsc.AllowedAddressPair;
102 import org.onosproject.vtnrsc.BindingHostId; 121 import org.onosproject.vtnrsc.BindingHostId;
122 +import org.onosproject.vtnrsc.DefaultFloatingIp;
103 import org.onosproject.vtnrsc.DefaultVirtualPort; 123 import org.onosproject.vtnrsc.DefaultVirtualPort;
104 import org.onosproject.vtnrsc.FixedIp; 124 import org.onosproject.vtnrsc.FixedIp;
105 import org.onosproject.vtnrsc.FloatingIp; 125 import org.onosproject.vtnrsc.FloatingIp;
126 +import org.onosproject.vtnrsc.FloatingIpId;
106 import org.onosproject.vtnrsc.RouterId; 127 import org.onosproject.vtnrsc.RouterId;
107 import org.onosproject.vtnrsc.RouterInterface; 128 import org.onosproject.vtnrsc.RouterInterface;
108 import org.onosproject.vtnrsc.SecurityGroup; 129 import org.onosproject.vtnrsc.SecurityGroup;
...@@ -183,6 +204,9 @@ public class VtnManager implements VtnService { ...@@ -183,6 +204,9 @@ public class VtnManager implements VtnService {
183 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) 204 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
184 protected RouterInterfaceService routerInterfaceService; 205 protected RouterInterfaceService routerInterfaceService;
185 206
207 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
208 + protected FlowRuleService flowRuleService;
209 +
186 private ApplicationId appId; 210 private ApplicationId appId;
187 private ClassifierService classifierService; 211 private ClassifierService classifierService;
188 private L2ForwardService l2ForwardService; 212 private L2ForwardService l2ForwardService;
...@@ -207,8 +231,12 @@ public class VtnManager implements VtnService { ...@@ -207,8 +231,12 @@ public class VtnManager implements VtnService {
207 private static final String EX_PORT_OF_DEVICE = "exPortOfDevice"; 231 private static final String EX_PORT_OF_DEVICE = "exPortOfDevice";
208 private static final String EX_PORT_MAP = "exPortMap"; 232 private static final String EX_PORT_MAP = "exPortMap";
209 private static final String DEFAULT_IP = "0.0.0.0"; 233 private static final String DEFAULT_IP = "0.0.0.0";
234 + private static final String FLOATINGSTORE = "vtn-floatingIp";
210 private static final String USERDATA_IP = "169.254.169.254"; 235 private static final String USERDATA_IP = "169.254.169.254";
211 private static final int SUBNET_NUM = 2; 236 private static final int SUBNET_NUM = 2;
237 + private static final int SNAT_TABLE = 40;
238 + private static final int SNAT_DEFAULT_RULE_PRIORITY = 0;
239 + private static final byte[] ZERO_MAC_ADDRESS = MacAddress.ZERO.toBytes();
212 240
213 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore; 241 private EventuallyConsistentMap<VirtualPortId, VirtualPort> vPortStore;
214 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController; 242 private EventuallyConsistentMap<IpAddress, Boolean> switchesOfController;
...@@ -216,8 +244,13 @@ public class VtnManager implements VtnService { ...@@ -216,8 +244,13 @@ public class VtnManager implements VtnService {
216 private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet; 244 private EventuallyConsistentMap<SubnetId, Map<HostId, Host>> hostsOfSubnet;
217 private EventuallyConsistentMap<TenantRouter, Boolean> routerInfFlagOfTenantRouter; 245 private EventuallyConsistentMap<TenantRouter, Boolean> routerInfFlagOfTenantRouter;
218 private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice; 246 private EventuallyConsistentMap<DeviceId, Port> exPortOfDevice;
247 + private EventuallyConsistentMap<IpAddress, FloatingIp> floatingIpStore;
219 private static ConsistentMap<String, String> exPortMap; 248 private static ConsistentMap<String, String> exPortMap;
220 249
250 + private VtnL3PacketProcessor l3PacketProcessor = new VtnL3PacketProcessor();
251 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
252 + protected PacketService packetService;
253 +
221 @Activate 254 @Activate
222 public void activate() { 255 public void activate() {
223 appId = coreService.registerApplication(APP_ID); 256 appId = coreService.registerApplication(APP_ID);
...@@ -238,18 +271,29 @@ public class VtnManager implements VtnService { ...@@ -238,18 +271,29 @@ public class VtnManager implements VtnService {
238 .register(TenantNetworkId.class) 271 .register(TenantNetworkId.class)
239 .register(Host.class) 272 .register(Host.class)
240 .register(TenantNetwork.class) 273 .register(TenantNetwork.class)
274 + .register(TenantNetworkId.class)
241 .register(TenantId.class) 275 .register(TenantId.class)
242 .register(SubnetId.class) 276 .register(SubnetId.class)
243 .register(VirtualPortId.class) 277 .register(VirtualPortId.class)
244 .register(VirtualPort.State.class) 278 .register(VirtualPort.State.class)
245 .register(AllowedAddressPair.class) 279 .register(AllowedAddressPair.class)
246 .register(FixedIp.class) 280 .register(FixedIp.class)
281 + .register(FloatingIp.class)
282 + .register(FloatingIpId.class)
283 + .register(FloatingIp.Status.class)
284 + .register(UUID.class)
285 + .register(DefaultFloatingIp.class)
247 .register(BindingHostId.class) 286 .register(BindingHostId.class)
248 .register(SecurityGroup.class) 287 .register(SecurityGroup.class)
249 .register(IpAddress.class) 288 .register(IpAddress.class)
250 .register(DefaultVirtualPort.class) 289 .register(DefaultVirtualPort.class)
251 .register(RouterId.class) 290 .register(RouterId.class)
252 .register(TenantRouter.class); 291 .register(TenantRouter.class);
292 + floatingIpStore = storageService
293 + .<IpAddress, FloatingIp>eventuallyConsistentMapBuilder()
294 + .withName(FLOATINGSTORE).withSerializer(serializer)
295 + .withTimestampProvider((k, v) -> clockService.getTimestamp())
296 + .build();
253 297
254 vPortStore = storageService 298 vPortStore = storageService
255 .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder() 299 .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder()
...@@ -295,6 +339,7 @@ public class VtnManager implements VtnService { ...@@ -295,6 +339,7 @@ public class VtnManager implements VtnService {
295 .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API))) 339 .withSerializer(Serializer.using(Arrays.asList(KryoNamespaces.API)))
296 .build(); 340 .build();
297 341
342 + packetService.addProcessor(l3PacketProcessor, PacketProcessor.director(0));
298 log.info("Started"); 343 log.info("Started");
299 } 344 }
300 345
...@@ -464,6 +509,9 @@ public class VtnManager implements VtnService { ...@@ -464,6 +509,9 @@ public class VtnManager implements VtnService {
464 // Save external port 509 // Save external port
465 Port export = getExPort(device.id()); 510 Port export = getExPort(device.id());
466 if (export != null) { 511 if (export != null) {
512 + classifierService.programExportPortArpClassifierRules(export,
513 + device.id(),
514 + type);
467 exPortOfDevice.put(device.id(), export); 515 exPortOfDevice.put(device.id(), export);
468 } 516 }
469 switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts()); 517 switchOfLocalHostPorts.put(device.id(), new NetworkOfLocalHostPorts());
...@@ -867,11 +915,14 @@ public class VtnManager implements VtnService { ...@@ -867,11 +915,14 @@ public class VtnManager implements VtnService {
867 915
868 @Override 916 @Override
869 public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) { 917 public void onFloatingIpDetected(VtnRscEventFeedback l3Feedback) {
918 + floatingIpStore.put(l3Feedback.floatingIp().floatingIp(),
919 + l3Feedback.floatingIp());
870 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_BIND); 920 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_BIND);
871 } 921 }
872 922
873 @Override 923 @Override
874 public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) { 924 public void onFloatingIpVanished(VtnRscEventFeedback l3Feedback) {
925 + floatingIpStore.remove(l3Feedback.floatingIp().floatingIp());
875 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_UNBIND); 926 programFloatingIpEvent(l3Feedback, VtnRscEvent.Type.FLOATINGIP_UNBIND);
876 } 927 }
877 928
...@@ -1100,8 +1151,6 @@ public class VtnManager implements VtnService { ...@@ -1100,8 +1151,6 @@ public class VtnManager implements VtnService {
1100 List gwIpMac = getGwIpAndMac(vmPort); 1151 List gwIpMac = getGwIpAndMac(vmPort);
1101 IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0); 1152 IpAddress dstVmGwIp = (IpAddress) gwIpMac.get(0);
1102 MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1); 1153 MacAddress dstVmGwMac = (MacAddress) gwIpMac.get(1);
1103 - List fGwIpMac = getGwIpAndMac(fipPort);
1104 - MacAddress fGwMac = (MacAddress) fGwIpMac.get(1);
1105 TenantNetwork vmNetwork = tenantNetworkService 1154 TenantNetwork vmNetwork = tenantNetworkService
1106 .getNetwork(vmPort.networkId()); 1155 .getNetwork(vmPort.networkId());
1107 TenantNetwork fipNetwork = tenantNetworkService 1156 TenantNetwork fipNetwork = tenantNetworkService
...@@ -1109,26 +1158,26 @@ public class VtnManager implements VtnService { ...@@ -1109,26 +1158,26 @@ public class VtnManager implements VtnService {
1109 // L3 downlink traffic flow 1158 // L3 downlink traffic flow
1110 MacAddress exPortMac = MacAddress.valueOf(exPort.annotations() 1159 MacAddress exPortMac = MacAddress.valueOf(exPort.annotations()
1111 .value(AnnotationKeys.PORT_MAC)); 1160 .value(AnnotationKeys.PORT_MAC));
1112 - classifierService.programArpClassifierRules(deviceId, floatingIp.floatingIp(),
1113 - fipNetwork.segmentationId(),
1114 - operation);
1115 classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(), 1161 classifierService.programL3ExPortClassifierRules(deviceId, exPort.number(),
1116 floatingIp.floatingIp(), operation); 1162 floatingIp.floatingIp(), operation);
1117 - DriverHandler handler = driverService.createHandler(deviceId);
1118 - arpService.programArpRules(handler, deviceId, floatingIp.floatingIp(),
1119 - fipNetwork.segmentationId(), exPortMac,
1120 - operation);
1121 dnatService.programRules(deviceId, floatingIp.floatingIp(), 1163 dnatService.programRules(deviceId, floatingIp.floatingIp(),
1122 - fGwMac, floatingIp.fixedIp(), 1164 + exPortMac, floatingIp.fixedIp(),
1123 l3vni, operation); 1165 l3vni, operation);
1124 1166
1167 + Subnet subnet = getSubnetOfFloatingIP(floatingIp);
1168 + IpPrefix ipPrefix = subnet.cidr();
1169 + snatService.programSnatSameSegmentUploadControllerRules(deviceId, l3vni,
1170 + floatingIp.fixedIp(),
1171 + floatingIp.floatingIp(),
1172 + ipPrefix,
1173 + operation);
1125 // L3 uplink traffic flow 1174 // L3 uplink traffic flow
1126 if (operation == Objective.Operation.ADD) { 1175 if (operation == Objective.Operation.ADD) {
1127 sendNorthSouthL3Flows(deviceId, floatingIp, dstVmGwIp, dstVmGwMac, 1176 sendNorthSouthL3Flows(deviceId, floatingIp, dstVmGwIp, dstVmGwMac,
1128 l3vni, vmNetwork, vmPort, host, operation); 1177 l3vni, vmNetwork, vmPort, host, operation);
1129 - l2ForwardService.programLocalOut(deviceId, 1178 + l2ForwardService
1130 - fipNetwork.segmentationId(), 1179 + .programExternalOut(deviceId, fipNetwork.segmentationId(),
1131 - exPort.number(), fGwMac, operation); 1180 + exPort.number(), exPortMac, operation);
1132 } else if (operation == Objective.Operation.REMOVE) { 1181 } else if (operation == Objective.Operation.REMOVE) {
1133 if (hostFlag || (!hostFlag 1182 if (hostFlag || (!hostFlag
1134 && routerInfFlagOfTenantRouter.get(tenantRouter) == null)) { 1183 && routerInfFlagOfTenantRouter.get(tenantRouter) == null)) {
...@@ -1147,15 +1196,13 @@ public class VtnManager implements VtnService { ...@@ -1147,15 +1196,13 @@ public class VtnManager implements VtnService {
1147 } 1196 }
1148 } 1197 }
1149 if (exPortFlag) { 1198 if (exPortFlag) {
1150 - l2ForwardService.programLocalOut(deviceId, 1199 + l2ForwardService.programExternalOut(deviceId,
1151 fipNetwork.segmentationId(), 1200 fipNetwork.segmentationId(),
1152 - exPort.number(), fGwMac, operation); 1201 + exPort.number(), exPortMac,
1202 + operation);
1153 } 1203 }
1204 + removeRulesInSnat(deviceId, floatingIp.fixedIp());
1154 } 1205 }
1155 - snatService.programRules(deviceId, l3vni, floatingIp.fixedIp(),
1156 - fGwMac, exPortMac,
1157 - floatingIp.floatingIp(),
1158 - fipNetwork.segmentationId(), operation);
1159 } 1206 }
1160 1207
1161 private Port getExPort(DeviceId deviceId) { 1208 private Port getExPort(DeviceId deviceId) {
...@@ -1280,4 +1327,306 @@ public class VtnManager implements VtnService { ...@@ -1280,4 +1327,306 @@ public class VtnManager implements VtnService {
1280 public static void setExPortName(String name) { 1327 public static void setExPortName(String name) {
1281 exPortMap.put(EX_PORT_KEY, name); 1328 exPortMap.put(EX_PORT_KEY, name);
1282 } 1329 }
1330 +
1331 + /**
1332 + * Packet processor responsible for forwarding packets along their paths.
1333 + */
1334 + private class VtnL3PacketProcessor implements PacketProcessor {
1335 +
1336 + @Override
1337 + public void process(PacketContext context) {
1338 + InboundPacket pkt = context.inPacket();
1339 + ConnectPoint connectPoint = pkt.receivedFrom();
1340 + DeviceId deviceId = connectPoint.deviceId();
1341 + Ethernet ethPkt = pkt.parsed();
1342 + if (ethPkt == null) {
1343 + return;
1344 + }
1345 + if (ethPkt.getEtherType() == Ethernet.TYPE_ARP) {
1346 + ARP arpPacket = (ARP) ethPkt.getPayload();
1347 + if ((arpPacket.getOpCode() == ARP.OP_REQUEST)) {
1348 + arprequestProcess(arpPacket, deviceId);
1349 + } else if (arpPacket.getOpCode() == ARP.OP_REPLY) {
1350 + arpresponceProcess(arpPacket, deviceId);
1351 + }
1352 + } else if (ethPkt.getEtherType() == Ethernet.TYPE_IPV4) {
1353 + if (ethPkt.getDestinationMAC().isMulticast()) {
1354 + return;
1355 + }
1356 + IPv4 ip = (IPv4) ethPkt.getPayload();
1357 + upStreamPacketProcessor(ip, deviceId);
1358 +
1359 + } else {
1360 + return;
1361 + }
1362 + }
1363 +
1364 + private void arprequestProcess(ARP arpPacket, DeviceId deviceId) {
1365 + MacAddress dstMac = MacAddress
1366 + .valueOf(arpPacket.getSenderHardwareAddress());
1367 + IpAddress srcIp = IpAddress.valueOf(IPv4
1368 + .toIPv4Address(arpPacket.getTargetProtocolAddress()));
1369 + IpAddress dstIp = IpAddress.valueOf(IPv4
1370 + .toIPv4Address(arpPacket.getSenderProtocolAddress()));
1371 + FloatingIp floatingIp = floatingIpStore.get(srcIp);
1372 + if (floatingIp == null) {
1373 + return;
1374 + }
1375 + DeviceId deviceIdOfFloatingIp = getDeviceIdOfFloatingIP(floatingIp);
1376 + if (!deviceId.equals(deviceIdOfFloatingIp)) {
1377 + return;
1378 + }
1379 + Port exPort = exPortOfDevice.get(deviceId);
1380 + MacAddress srcMac = MacAddress.valueOf(exPort.annotations()
1381 + .value(AnnotationKeys.PORT_MAC));
1382 + if (!downloadSnatRules(deviceId, srcMac, srcIp, dstMac, dstIp,
1383 + floatingIp)) {
1384 + return;
1385 + }
1386 + Ethernet ethernet = buildArpResponse(dstIp, dstMac, srcIp, srcMac);
1387 + if (ethernet != null) {
1388 + sendPacketOut(deviceId, exPort.number(), ethernet);
1389 + }
1390 + }
1391 +
1392 + private void arpresponceProcess(ARP arpPacket, DeviceId deviceId) {
1393 + MacAddress srcMac = MacAddress
1394 + .valueOf(arpPacket.getTargetHardwareAddress());
1395 + MacAddress dstMac = MacAddress
1396 + .valueOf(arpPacket.getSenderHardwareAddress());
1397 + IpAddress srcIp = IpAddress.valueOf(IPv4
1398 + .toIPv4Address(arpPacket.getTargetProtocolAddress()));
1399 + IpAddress dstIp = IpAddress.valueOf(IPv4
1400 + .toIPv4Address(arpPacket.getSenderProtocolAddress()));
1401 + FloatingIp floatingIp = floatingIpStore.get(srcIp);
1402 + if (floatingIp == null) {
1403 + return;
1404 + }
1405 + DeviceId deviceIdOfFloatingIp = getDeviceIdOfFloatingIP(floatingIp);
1406 + if (!deviceId.equals(deviceIdOfFloatingIp)) {
1407 + return;
1408 + }
1409 + if (!downloadSnatRules(deviceId, srcMac, srcIp, dstMac, dstIp,
1410 + floatingIp)) {
1411 + return;
1412 + }
1413 + }
1414 +
1415 + private void upStreamPacketProcessor(IPv4 ipPacket, DeviceId deviceId) {
1416 + IpAddress srcIp = IpAddress.valueOf(ipPacket.getSourceAddress());
1417 + IpAddress dstIp = IpAddress.valueOf(ipPacket.getDestinationAddress());
1418 + FloatingIp floatingIp = null;
1419 + Collection<FloatingIp> floatingIps = floatingIpService
1420 + .getFloatingIps();
1421 + Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps)
1422 + .stream().collect(Collectors.toSet());
1423 + for (FloatingIp f : floatingIpSet) {
1424 + IpAddress fixIp = f.fixedIp();
1425 + if (fixIp != null && fixIp.equals(srcIp)) {
1426 + floatingIp = f;
1427 + break;
1428 + }
1429 + }
1430 + if (floatingIp == null) {
1431 + return;
1432 + }
1433 + Subnet subnet = getSubnetOfFloatingIP(floatingIp);
1434 + IpAddress gwIp = subnet.gatewayIp();
1435 + Port exportPort = exPortOfDevice.get(deviceId);
1436 + MacAddress exPortMac = MacAddress.valueOf(exportPort.annotations()
1437 + .value(AnnotationKeys.PORT_MAC));
1438 + IpPrefix ipPrefix = subnet.cidr();
1439 + if (ipPrefix == null) {
1440 + return;
1441 + }
1442 + int mask = ipPrefix.prefixLength();
1443 + if (mask <= 0) {
1444 + return;
1445 + }
1446 + Ethernet ethernet = null;
1447 + // if the same ip segment
1448 + if (IpUtil.checkSameSegment(floatingIp.floatingIp(), dstIp, mask)) {
1449 + ethernet = buildArpRequest(dstIp, floatingIp.floatingIp(),
1450 + exPortMac);
1451 + } else {
1452 + ethernet = buildArpRequest(gwIp, floatingIp.floatingIp(),
1453 + exPortMac);
1454 + }
1455 + if (ethernet != null) {
1456 + sendPacketOut(deviceId, exportPort.number(), ethernet);
1457 + }
1458 + }
1459 + }
1460 +
1461 + private Ethernet buildArpRequest(IpAddress targetIp, IpAddress sourceIp,
1462 + MacAddress sourceMac) {
1463 + ARP arp = new ARP();
1464 + arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
1465 + .setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
1466 + .setProtocolType(ARP.PROTO_TYPE_IP)
1467 + .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH)
1468 + .setOpCode(ARP.OP_REQUEST);
1469 +
1470 + arp.setSenderHardwareAddress(sourceMac.toBytes())
1471 + .setSenderProtocolAddress(sourceIp.getIp4Address().toInt())
1472 + .setTargetHardwareAddress(ZERO_MAC_ADDRESS)
1473 + .setTargetProtocolAddress(targetIp.getIp4Address().toInt());
1474 +
1475 + Ethernet ethernet = new Ethernet();
1476 + ethernet.setEtherType(Ethernet.TYPE_ARP)
1477 + .setDestinationMACAddress(MacAddress.BROADCAST)
1478 + .setSourceMACAddress(sourceMac)
1479 + .setPayload(arp);
1480 +
1481 + ethernet.setPad(true);
1482 + return ethernet;
1483 + }
1484 +
1485 + private Ethernet buildArpResponse(IpAddress targetIp, MacAddress targetMac,
1486 + IpAddress sourceIp, MacAddress sourceMac) {
1487 + ARP arp = new ARP();
1488 + arp.setHardwareType(ARP.HW_TYPE_ETHERNET)
1489 + .setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH)
1490 + .setProtocolType(ARP.PROTO_TYPE_IP)
1491 + .setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH)
1492 + .setOpCode(ARP.OP_REPLY);
1493 +
1494 + arp.setSenderHardwareAddress(sourceMac.toBytes())
1495 + .setSenderProtocolAddress(sourceIp.getIp4Address().toInt())
1496 + .setTargetHardwareAddress(targetMac.toBytes())
1497 + .setTargetProtocolAddress(targetIp.getIp4Address().toInt());
1498 +
1499 + Ethernet ethernet = new Ethernet();
1500 + ethernet.setEtherType(Ethernet.TYPE_ARP)
1501 + .setDestinationMACAddress(targetMac)
1502 + .setSourceMACAddress(sourceMac)
1503 + .setPayload(arp);
1504 +
1505 + ethernet.setPad(true);
1506 +
1507 + return ethernet;
1508 + }
1509 +
1510 + private void sendPacketOut(DeviceId deviceId, PortNumber portNumber,
1511 + Ethernet payload) {
1512 + TrafficTreatment treatment = DefaultTrafficTreatment.builder()
1513 + .setOutput(portNumber).build();
1514 + OutboundPacket packet = new DefaultOutboundPacket(deviceId, treatment,
1515 + ByteBuffer
1516 + .wrap(payload
1517 + .serialize()));
1518 + packetService.emit(packet);
1519 + }
1520 +
1521 + private Subnet getSubnetOfFloatingIP(FloatingIp floatingIp) {
1522 + DeviceId exVmPortId = DeviceId
1523 + .deviceId(floatingIp.id().floatingIpId().toString());
1524 + Collection<VirtualPort> exVmPortList = virtualPortService
1525 + .getPorts(exVmPortId);
1526 + VirtualPort exVmPort = null;
1527 + if (exVmPortList != null) {
1528 + exVmPort = exVmPortList.iterator().next();
1529 + }
1530 + if (exVmPort == null) {
1531 + return null;
1532 + }
1533 + Set<FixedIp> fixedIps = exVmPort.fixedIps();
1534 + SubnetId subnetId = null;
1535 + for (FixedIp f : fixedIps) {
1536 + IpAddress fp = f.ip();
1537 + if (fp.equals(floatingIp.floatingIp())) {
1538 + subnetId = f.subnetId();
1539 + break;
1540 + }
1541 + }
1542 + if (subnetId == null) {
1543 + return null;
1544 + }
1545 + Subnet subnet = subnetService.getSubnet(subnetId);
1546 + return subnet;
1547 + }
1548 +
1549 + private DeviceId getDeviceIdOfFloatingIP(FloatingIp floatingIp) {
1550 + VirtualPortId vmPortId = floatingIp.portId();
1551 + VirtualPort vmPort = virtualPortService.getPort(vmPortId);
1552 + if (vmPort == null) {
1553 + vmPort = VtnData.getPort(vPortStore, vmPortId);
1554 + }
1555 + Set<Host> hostSet = hostService.getHostsByMac(vmPort.macAddress());
1556 + Host host = null;
1557 + for (Host h : hostSet) {
1558 + String ifaceid = h.annotations().value(IFACEID);
1559 + if (ifaceid != null && ifaceid.equals(vmPortId.portId())) {
1560 + host = h;
1561 + break;
1562 + }
1563 + }
1564 + if (host == null) {
1565 + return null;
1566 + } else {
1567 + return host.location().deviceId();
1568 + }
1569 + }
1570 +
1571 + private boolean downloadSnatRules(DeviceId deviceId, MacAddress srcMac,
1572 + IpAddress srcIp, MacAddress dstMac,
1573 + IpAddress dstIp, FloatingIp floatingIp) {
1574 + TenantNetwork exNetwork = tenantNetworkService
1575 + .getNetwork(floatingIp.networkId());
1576 + IpAddress fixedIp = floatingIp.fixedIp();
1577 + VirtualPortId vmPortId = floatingIp.portId();
1578 + VirtualPort vmPort = virtualPortService.getPort(vmPortId);
1579 + if (vmPort == null) {
1580 + vmPort = VtnData.getPort(vPortStore, vmPortId);
1581 + }
1582 + Subnet subnet = getSubnetOfFloatingIP(floatingIp);
1583 + IpPrefix ipPrefix = subnet.cidr();
1584 + IpAddress gwIp = subnet.gatewayIp();
1585 + if (ipPrefix == null) {
1586 + return false;
1587 + }
1588 + int mask = ipPrefix.prefixLength();
1589 + if (mask <= 0) {
1590 + return false;
1591 + }
1592 + TenantRouter tenantRouter = TenantRouter
1593 + .tenantRouter(floatingIp.tenantId(), floatingIp.routerId());
1594 + SegmentationId l3vni = vtnRscService.getL3vni(tenantRouter);
1595 + // if the same ip segment
1596 + if (IpUtil.checkSameSegment(srcIp, dstIp, mask)) {
1597 + snatService.programSnatSameSegmentRules(deviceId, l3vni, fixedIp,
1598 + dstIp, dstMac, srcMac,
1599 + srcIp,
1600 + exNetwork.segmentationId(),
1601 + Objective.Operation.ADD);
1602 + if (dstIp.equals(gwIp)) {
1603 + snatService
1604 + .programSnatDiffSegmentRules(deviceId, l3vni, fixedIp,
1605 + dstMac, srcMac, srcIp,
1606 + exNetwork.segmentationId(),
1607 + Objective.Operation.ADD);
1608 + }
1609 + }
1610 + return true;
1611 + }
1612 +
1613 + private void removeRulesInSnat(DeviceId deviceId, IpAddress fixedIp) {
1614 + for (FlowEntry f : flowRuleService.getFlowEntries(deviceId)) {
1615 + if (f.tableId() == SNAT_TABLE
1616 + && f.priority() > SNAT_DEFAULT_RULE_PRIORITY) {
1617 + String srcIp = f.selector()
1618 + .getCriterion(Criterion.Type.IPV4_SRC).toString();
1619 + int priority = f.priority();
1620 + if (srcIp != null && srcIp.contains(fixedIp.toString())) {
1621 + log.info("Match snat rules bob");
1622 + TrafficSelector selector = f.selector();
1623 + TrafficTreatment treatment = f.treatment();
1624 + snatService.removeSnatRules(deviceId, selector, treatment,
1625 + priority,
1626 + Objective.Operation.REMOVE);
1627 +
1628 + }
1629 + }
1630 + }
1631 + }
1283 } 1632 }
......
...@@ -20,8 +20,10 @@ import org.onlab.packet.IpPrefix; ...@@ -20,8 +20,10 @@ import org.onlab.packet.IpPrefix;
20 import org.onlab.packet.MacAddress; 20 import org.onlab.packet.MacAddress;
21 import org.onosproject.core.ApplicationId; 21 import org.onosproject.core.ApplicationId;
22 import org.onosproject.net.DeviceId; 22 import org.onosproject.net.DeviceId;
23 +import org.onosproject.net.Port;
23 import org.onosproject.net.PortNumber; 24 import org.onosproject.net.PortNumber;
24 import org.onosproject.net.flowobjective.Objective; 25 import org.onosproject.net.flowobjective.Objective;
26 +import org.onosproject.net.flowobjective.Objective.Operation;
25 import org.onosproject.vtnrsc.SegmentationId; 27 import org.onosproject.vtnrsc.SegmentationId;
26 28
27 /** 29 /**
...@@ -134,4 +136,16 @@ public interface ClassifierService { ...@@ -134,4 +136,16 @@ public interface ClassifierService {
134 IpAddress dstIp, MacAddress dstmac, 136 IpAddress dstIp, MacAddress dstmac,
135 SegmentationId actionVni, 137 SegmentationId actionVni,
136 Objective.Operation type); 138 Objective.Operation type);
139 +
140 + /**
141 + * Assemble the export port Arp Classifier table rules.
142 + * Match: export port.
143 + * Action: upload packet to controller.
144 + *
145 + * @param exportPort export port of ovs
146 + * @param deviceId Device Id
147 + * @param type the operation type of the flow rules
148 + */
149 + void programExportPortArpClassifierRules(Port exportPort, DeviceId deviceId,
150 + Operation type);
137 } 151 }
......
...@@ -79,6 +79,21 @@ public interface L2ForwardService { ...@@ -79,6 +79,21 @@ public interface L2ForwardService {
79 Objective.Operation type); 79 Objective.Operation type);
80 80
81 /** 81 /**
82 + * The external out rule that message matches Table(50).
83 + * Match: external port mac and vnid.
84 + * Action: output external port.
85 + *
86 + * @param deviceId Device Id
87 + * @param segmentationId the vnid of the host belong to
88 + * @param outPort the ingress port of the external port
89 + * @param sourceMac the mac of the external port
90 + * @param type the operation of the flow
91 + */
92 + void programExternalOut(DeviceId deviceId, SegmentationId segmentationId,
93 + PortNumber outPort, MacAddress sourceMac,
94 + Objective.Operation type);
95 +
96 + /**
82 * The tunnel out rule that message matches Table(50). 97 * The tunnel out rule that message matches Table(50).
83 * Match: host mac and vnid. 98 * Match: host mac and vnid.
84 * Action: output tunnel port. 99 * Action: output tunnel port.
......
...@@ -16,8 +16,11 @@ ...@@ -16,8 +16,11 @@
16 package org.onosproject.vtn.table; 16 package org.onosproject.vtn.table;
17 17
18 import org.onlab.packet.IpAddress; 18 import org.onlab.packet.IpAddress;
19 +import org.onlab.packet.IpPrefix;
19 import org.onlab.packet.MacAddress; 20 import org.onlab.packet.MacAddress;
20 import org.onosproject.net.DeviceId; 21 import org.onosproject.net.DeviceId;
22 +import org.onosproject.net.flow.TrafficSelector;
23 +import org.onosproject.net.flow.TrafficTreatment;
21 import org.onosproject.net.flowobjective.Objective; 24 import org.onosproject.net.flowobjective.Objective;
22 import org.onosproject.vtnrsc.SegmentationId; 25 import org.onosproject.vtnrsc.SegmentationId;
23 26
...@@ -30,6 +33,25 @@ public interface SnatService { ...@@ -30,6 +33,25 @@ public interface SnatService {
30 33
31 /** 34 /**
32 * Assemble the SNAT table rules. 35 * Assemble the SNAT table rules.
36 + * Match: ipv4 type, vnid, destination ip and source ip.
37 + * Action: set eth_src, set eth_dst, set ip_src, set vnid and goto L2Forward Table(50).
38 + *
39 + * @param deviceId Device Id
40 + * @param matchVni the vni of L3 network
41 + * @param srcIP source ip
42 + * @param dstIP destination ip
43 + * @param ethDst external gateway mac
44 + * @param ethSrc external port mac
45 + * @param ipSrc floating ip
46 + * @param actionVni external network VNI
47 + * @param type the operation type of the flow rules
48 + */
49 + void programSnatSameSegmentRules(DeviceId deviceId, SegmentationId matchVni,
50 + IpAddress srcIP, IpAddress dstIP, MacAddress ethDst,
51 + MacAddress ethSrc, IpAddress ipSrc,
52 + SegmentationId actionVni, Objective.Operation type);
53 + /**
54 + * Assemble the SNAT table rules.
33 * Match: ipv4 type, vnid and source ip. 55 * Match: ipv4 type, vnid and source ip.
34 * Action: set eth_src, set eth_dst, set ip_src, set vnid and goto L2Forward Table(50). 56 * Action: set eth_src, set eth_dst, set ip_src, set vnid and goto L2Forward Table(50).
35 * 57 *
...@@ -42,8 +64,39 @@ public interface SnatService { ...@@ -42,8 +64,39 @@ public interface SnatService {
42 * @param actionVni external network VNI 64 * @param actionVni external network VNI
43 * @param type the operation type of the flow rules 65 * @param type the operation type of the flow rules
44 */ 66 */
45 - void programRules(DeviceId deviceId, SegmentationId matchVni, 67 + void programSnatDiffSegmentRules(DeviceId deviceId, SegmentationId matchVni,
46 IpAddress srcIP, MacAddress ethDst, 68 IpAddress srcIP, MacAddress ethDst,
47 MacAddress ethSrc, IpAddress ipSrc, 69 MacAddress ethSrc, IpAddress ipSrc,
48 SegmentationId actionVni, Objective.Operation type); 70 SegmentationId actionVni, Objective.Operation type);
71 +
72 + /**
73 + * Assemble the SNAT table rules.
74 + * Match: ipv4 type, vnid, destination ip and source ip.
75 + * Action: upload to controller.
76 + *
77 + * @param deviceId Device Id
78 + * @param matchVni the vni of L3 network
79 + * @param srcIP source ip
80 + * @param dstIP destination ip
81 + * @param type the operation type of the flow rules
82 + */
83 + void programSnatSameSegmentUploadControllerRules(DeviceId deviceId,
84 + SegmentationId matchVni,
85 + IpAddress srcIP,
86 + IpAddress dstIP,
87 + IpPrefix prefix,
88 + Objective.Operation type);
89 +
90 + /**
91 + * Remove the SNAT table rules.
92 + *
93 + * @param deviceId Device Id
94 + * @param selector selector of rules
95 + * @param treatment treatment of rules
96 + * @param priority priority of rules
97 + * @param type the operation type of the flow rules
98 + */
99 + void removeSnatRules(DeviceId deviceId, TrafficSelector selector,
100 + TrafficTreatment treatment, int priority,
101 + Objective.Operation type);
49 } 102 }
......
...@@ -28,6 +28,7 @@ import org.onlab.packet.IpPrefix; ...@@ -28,6 +28,7 @@ import org.onlab.packet.IpPrefix;
28 import org.onlab.packet.MacAddress; 28 import org.onlab.packet.MacAddress;
29 import org.onosproject.core.ApplicationId; 29 import org.onosproject.core.ApplicationId;
30 import org.onosproject.net.DeviceId; 30 import org.onosproject.net.DeviceId;
31 +import org.onosproject.net.Port;
31 import org.onosproject.net.PortNumber; 32 import org.onosproject.net.PortNumber;
32 import org.onosproject.net.flow.DefaultTrafficSelector; 33 import org.onosproject.net.flow.DefaultTrafficSelector;
33 import org.onosproject.net.flow.DefaultTrafficTreatment; 34 import org.onosproject.net.flow.DefaultTrafficTreatment;
...@@ -40,6 +41,7 @@ import org.onosproject.net.flowobjective.FlowObjectiveService; ...@@ -40,6 +41,7 @@ import org.onosproject.net.flowobjective.FlowObjectiveService;
40 import org.onosproject.net.flowobjective.ForwardingObjective; 41 import org.onosproject.net.flowobjective.ForwardingObjective;
41 import org.onosproject.net.flowobjective.ForwardingObjective.Flag; 42 import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
42 import org.onosproject.net.flowobjective.Objective; 43 import org.onosproject.net.flowobjective.Objective;
44 +import org.onosproject.net.flowobjective.Objective.Operation;
43 import org.onosproject.vtn.table.ClassifierService; 45 import org.onosproject.vtn.table.ClassifierService;
44 import org.onosproject.vtnrsc.SegmentationId; 46 import org.onosproject.vtnrsc.SegmentationId;
45 import org.slf4j.Logger; 47 import org.slf4j.Logger;
...@@ -242,4 +244,24 @@ public class ClassifierServiceImpl implements ClassifierService { ...@@ -242,4 +244,24 @@ public class ClassifierServiceImpl implements ClassifierService {
242 flowObjectiveService.forward(deviceId, objective.remove()); 244 flowObjectiveService.forward(deviceId, objective.remove());
243 } 245 }
244 } 246 }
247 +
248 + @Override
249 + public void programExportPortArpClassifierRules(Port exportPort,
250 + DeviceId deviceId,
251 + Operation type) {
252 + TrafficSelector selector = DefaultTrafficSelector.builder()
253 + .matchEthType(EtherType.ARP.ethType().toShort())
254 + .matchInPort(exportPort.number()).build();
255 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
256 + treatment.add(Instructions.createOutput(PortNumber.CONTROLLER));
257 + ForwardingObjective.Builder objective = DefaultForwardingObjective
258 + .builder().withTreatment(treatment.build())
259 + .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC)
260 + .withPriority(L3_CLASSIFIER_PRIORITY);
261 + if (type.equals(Objective.Operation.ADD)) {
262 + flowObjectiveService.forward(deviceId, objective.add());
263 + } else {
264 + flowObjectiveService.forward(deviceId, objective.remove());
265 + }
266 + }
245 } 267 }
......
...@@ -176,6 +176,28 @@ public final class L2ForwardServiceImpl implements L2ForwardService { ...@@ -176,6 +176,28 @@ public final class L2ForwardServiceImpl implements L2ForwardService {
176 } 176 }
177 177
178 @Override 178 @Override
179 + public void programExternalOut(DeviceId deviceId,
180 + SegmentationId segmentationId,
181 + PortNumber outPort, MacAddress sourceMac,
182 + Objective.Operation type) {
183 + TrafficSelector selector = DefaultTrafficSelector.builder()
184 + .matchTunnelId(Long.parseLong(segmentationId.toString()))
185 + .matchEthSrc(sourceMac).build();
186 + TrafficTreatment treatment = DefaultTrafficTreatment.builder()
187 + .setOutput(outPort).build();
188 + ForwardingObjective.Builder objective = DefaultForwardingObjective
189 + .builder().withTreatment(treatment).withSelector(selector)
190 + .fromApp(appId).withFlag(Flag.SPECIFIC)
191 + .withPriority(MAC_PRIORITY);
192 + if (type.equals(Objective.Operation.ADD)) {
193 + flowObjectiveService.forward(deviceId, objective.add());
194 + } else {
195 + flowObjectiveService.forward(deviceId, objective.remove());
196 + }
197 +
198 + }
199 +
200 + @Override
179 public void programTunnelOut(DeviceId deviceId, 201 public void programTunnelOut(DeviceId deviceId,
180 SegmentationId segmentationId, 202 SegmentationId segmentationId,
181 PortNumber tunnelOutPort, MacAddress dstMac, 203 PortNumber tunnelOutPort, MacAddress dstMac,
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
16 package org.onosproject.vtn.table.impl; 16 package org.onosproject.vtn.table.impl;
17 17
18 import static com.google.common.base.Preconditions.checkNotNull; 18 import static com.google.common.base.Preconditions.checkNotNull;
19 -import static org.slf4j.LoggerFactory.getLogger;
20 19
21 import org.onlab.osgi.DefaultServiceDirectory; 20 import org.onlab.osgi.DefaultServiceDirectory;
22 import org.onlab.osgi.ServiceDirectory; 21 import org.onlab.osgi.ServiceDirectory;
...@@ -26,26 +25,29 @@ import org.onlab.packet.IpPrefix; ...@@ -26,26 +25,29 @@ import org.onlab.packet.IpPrefix;
26 import org.onlab.packet.MacAddress; 25 import org.onlab.packet.MacAddress;
27 import org.onosproject.core.ApplicationId; 26 import org.onosproject.core.ApplicationId;
28 import org.onosproject.net.DeviceId; 27 import org.onosproject.net.DeviceId;
28 +import org.onosproject.net.PortNumber;
29 import org.onosproject.net.flow.DefaultTrafficSelector; 29 import org.onosproject.net.flow.DefaultTrafficSelector;
30 import org.onosproject.net.flow.DefaultTrafficTreatment; 30 import org.onosproject.net.flow.DefaultTrafficTreatment;
31 import org.onosproject.net.flow.TrafficSelector; 31 import org.onosproject.net.flow.TrafficSelector;
32 import org.onosproject.net.flow.TrafficTreatment; 32 import org.onosproject.net.flow.TrafficTreatment;
33 +import org.onosproject.net.flow.instructions.Instructions;
33 import org.onosproject.net.flowobjective.DefaultForwardingObjective; 34 import org.onosproject.net.flowobjective.DefaultForwardingObjective;
34 import org.onosproject.net.flowobjective.FlowObjectiveService; 35 import org.onosproject.net.flowobjective.FlowObjectiveService;
35 import org.onosproject.net.flowobjective.ForwardingObjective; 36 import org.onosproject.net.flowobjective.ForwardingObjective;
36 import org.onosproject.net.flowobjective.ForwardingObjective.Flag; 37 import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
37 import org.onosproject.net.flowobjective.Objective; 38 import org.onosproject.net.flowobjective.Objective;
39 +import org.onosproject.net.flowobjective.Objective.Operation;
38 import org.onosproject.vtn.table.SnatService; 40 import org.onosproject.vtn.table.SnatService;
39 import org.onosproject.vtnrsc.SegmentationId; 41 import org.onosproject.vtnrsc.SegmentationId;
40 -import org.slf4j.Logger;
41 42
42 /** 43 /**
43 * Provides implementation of SnatService. 44 * Provides implementation of SnatService.
44 */ 45 */
45 public class SnatServiceImpl implements SnatService { 46 public class SnatServiceImpl implements SnatService {
46 - private final Logger log = getLogger(getClass());
47 47
48 - private static final int SNAT_PRIORITY = 0xffff; 48 + private static final int SNAT_SAME_SEG_PRIORITY = 0xffff;
49 + private static final int SNAT_SAME_SEG_CON_PRIORITY = 0xfff0;
50 + private static final int SNAT_DIFF_SEG_PRIORITY = 0xffe0;
49 private static final int PREFIC_LENGTH = 32; 51 private static final int PREFIC_LENGTH = 32;
50 52
51 private final FlowObjectiveService flowObjectiveService; 53 private final FlowObjectiveService flowObjectiveService;
...@@ -63,7 +65,32 @@ public class SnatServiceImpl implements SnatService { ...@@ -63,7 +65,32 @@ public class SnatServiceImpl implements SnatService {
63 } 65 }
64 66
65 @Override 67 @Override
66 - public void programRules(DeviceId deviceId, SegmentationId matchVni, 68 + public void programSnatSameSegmentRules(DeviceId deviceId, SegmentationId matchVni,
69 + IpAddress srcIP, IpAddress dstIP, MacAddress ethDst,
70 + MacAddress ethSrc, IpAddress ipSrc,
71 + SegmentationId actionVni, Objective.Operation type) {
72 + TrafficSelector selector = DefaultTrafficSelector.builder()
73 + .matchEthType(Ethernet.TYPE_IPV4)
74 + .matchTunnelId(Long.parseLong(matchVni.segmentationId()))
75 + .matchIPSrc(IpPrefix.valueOf(srcIP, PREFIC_LENGTH))
76 + .matchIPDst(IpPrefix.valueOf(dstIP, PREFIC_LENGTH)).build();
77 +
78 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
79 + treatment.setEthDst(ethDst).setEthSrc(ethSrc).setIpSrc(ipSrc)
80 + .setTunnelId(Long.parseLong(actionVni.segmentationId()));
81 + ForwardingObjective.Builder objective = DefaultForwardingObjective
82 + .builder().withTreatment(treatment.build())
83 + .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC)
84 + .withPriority(SNAT_SAME_SEG_PRIORITY);
85 + if (type.equals(Objective.Operation.ADD)) {
86 + flowObjectiveService.forward(deviceId, objective.add());
87 + } else {
88 + flowObjectiveService.forward(deviceId, objective.remove());
89 + }
90 + }
91 +
92 + @Override
93 + public void programSnatDiffSegmentRules(DeviceId deviceId, SegmentationId matchVni,
67 IpAddress srcIP, MacAddress ethDst, 94 IpAddress srcIP, MacAddress ethDst,
68 MacAddress ethSrc, IpAddress ipSrc, 95 MacAddress ethSrc, IpAddress ipSrc,
69 SegmentationId actionVni, Objective.Operation type) { 96 SegmentationId actionVni, Objective.Operation type) {
...@@ -78,12 +105,51 @@ public class SnatServiceImpl implements SnatService { ...@@ -78,12 +105,51 @@ public class SnatServiceImpl implements SnatService {
78 ForwardingObjective.Builder objective = DefaultForwardingObjective 105 ForwardingObjective.Builder objective = DefaultForwardingObjective
79 .builder().withTreatment(treatment.build()) 106 .builder().withTreatment(treatment.build())
80 .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC) 107 .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC)
81 - .withPriority(SNAT_PRIORITY); 108 + .withPriority(SNAT_DIFF_SEG_PRIORITY);
109 + if (type.equals(Objective.Operation.ADD)) {
110 + flowObjectiveService.forward(deviceId, objective.add());
111 + } else {
112 + flowObjectiveService.forward(deviceId, objective.remove());
113 + }
114 + }
115 +
116 + @Override
117 + public void programSnatSameSegmentUploadControllerRules(DeviceId deviceId,
118 + SegmentationId matchVni,
119 + IpAddress srcIP,
120 + IpAddress dstIP,
121 + IpPrefix prefix,
122 + Operation type) {
123 +
124 + TrafficSelector selector = DefaultTrafficSelector.builder()
125 + .matchEthType(Ethernet.TYPE_IPV4)
126 + .matchTunnelId(Long.parseLong(matchVni.segmentationId()))
127 + .matchIPSrc(IpPrefix.valueOf(srcIP, PREFIC_LENGTH))
128 + .matchIPDst(IpPrefix.valueOf(dstIP, prefix.prefixLength()))
129 + .build();
130 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
131 + treatment.add(Instructions.createOutput(PortNumber.CONTROLLER));
132 + ForwardingObjective.Builder objective = DefaultForwardingObjective
133 + .builder().withTreatment(treatment.build())
134 + .withSelector(selector).fromApp(appId).withFlag(Flag.SPECIFIC)
135 + .withPriority(SNAT_SAME_SEG_CON_PRIORITY);
136 + if (type.equals(Objective.Operation.ADD)) {
137 + flowObjectiveService.forward(deviceId, objective.add());
138 + } else {
139 + flowObjectiveService.forward(deviceId, objective.remove());
140 + }
141 + }
142 +
143 + @Override
144 + public void removeSnatRules(DeviceId deviceId, TrafficSelector selector,
145 + TrafficTreatment treatment, int priority,
146 + Objective.Operation type) {
147 + ForwardingObjective.Builder objective = DefaultForwardingObjective
148 + .builder().withTreatment(treatment).withSelector(selector)
149 + .fromApp(appId).withFlag(Flag.SPECIFIC).withPriority(priority);
82 if (type.equals(Objective.Operation.ADD)) { 150 if (type.equals(Objective.Operation.ADD)) {
83 - log.debug("RouteRules-->ADD");
84 flowObjectiveService.forward(deviceId, objective.add()); 151 flowObjectiveService.forward(deviceId, objective.add());
85 } else { 152 } else {
86 - log.debug("RouteRules-->REMOVE");
87 flowObjectiveService.forward(deviceId, objective.remove()); 153 flowObjectiveService.forward(deviceId, objective.remove());
88 } 154 }
89 } 155 }
......
1 +/*
2 + * Copyright 2016-present Open Networking Laboratory
3 + *
4 + * Licensed under the Apache License, Version 2.0 (the "License");
5 + * you may not use this file except in compliance with the License.
6 + * You may obtain a copy of the License at
7 + *
8 + * http://www.apache.org/licenses/LICENSE-2.0
9 + *
10 + * Unless required by applicable law or agreed to in writing, software
11 + * distributed under the License is distributed on an "AS IS" BASIS,
12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 + * See the License for the specific language governing permissions and
14 + * limitations under the License.
15 + */
16 +package org.onosproject.vtn.util;
17 +
18 +import org.onlab.packet.IpAddress;
19 +
20 +/**
21 + * IpUtil utility class.
22 + */
23 +public final class IpUtil {
24 +
25 + private IpUtil() {
26 + }
27 +
28 + /**
29 + * check source Ip and destination Ip in same Subnet.
30 + *
31 + * @param srcIp source Ip
32 + * @param dstIp destination
33 + * @param masks netmask length
34 + * @return boolean
35 + */
36 + public static boolean checkSameSegment(IpAddress srcIp, IpAddress dstIp,
37 + int mask) {
38 + String[] ips = srcIp.toString().split("\\.");
39 + int ipAddr = (Integer.parseInt(ips[0]) << 24)
40 + | (Integer.parseInt(ips[1]) << 16)
41 + | (Integer.parseInt(ips[2]) << 8)
42 + | Integer.parseInt(ips[3]);
43 + int netmask = 0xFFFFFFFF << (32 - mask);
44 + String[] cidrIps = dstIp.toString().split("\\.");
45 + int cidrIpAddr = (Integer.parseInt(cidrIps[0]) << 24)
46 + | (Integer.parseInt(cidrIps[1]) << 16)
47 + | (Integer.parseInt(cidrIps[2]) << 8)
48 + | Integer.parseInt(cidrIps[3]);
49 +
50 + return (ipAddr & netmask) == (cidrIpAddr & netmask);
51 + }
52 +}