[ONOS-4511] Fix the bug about deleting floatingip or
routerInterface:When deleting floatingip or routerInterface, some flows are not deleted. Change-Id: I9fc547e53be9bf2f32edf6f4eb3bc6428ca5d27c
Showing
1 changed file
with
168 additions
and
50 deletions
... | @@ -103,6 +103,7 @@ import org.onosproject.vtnrsc.BindingHostId; | ... | @@ -103,6 +103,7 @@ import org.onosproject.vtnrsc.BindingHostId; |
103 | import org.onosproject.vtnrsc.DefaultVirtualPort; | 103 | import org.onosproject.vtnrsc.DefaultVirtualPort; |
104 | import org.onosproject.vtnrsc.FixedIp; | 104 | import org.onosproject.vtnrsc.FixedIp; |
105 | import org.onosproject.vtnrsc.FloatingIp; | 105 | import org.onosproject.vtnrsc.FloatingIp; |
106 | +import org.onosproject.vtnrsc.RouterId; | ||
106 | import org.onosproject.vtnrsc.RouterInterface; | 107 | import org.onosproject.vtnrsc.RouterInterface; |
107 | import org.onosproject.vtnrsc.SecurityGroup; | 108 | import org.onosproject.vtnrsc.SecurityGroup; |
108 | import org.onosproject.vtnrsc.SegmentationId; | 109 | import org.onosproject.vtnrsc.SegmentationId; |
... | @@ -246,7 +247,9 @@ public class VtnManager implements VtnService { | ... | @@ -246,7 +247,9 @@ public class VtnManager implements VtnService { |
246 | .register(BindingHostId.class) | 247 | .register(BindingHostId.class) |
247 | .register(SecurityGroup.class) | 248 | .register(SecurityGroup.class) |
248 | .register(IpAddress.class) | 249 | .register(IpAddress.class) |
249 | - .register(DefaultVirtualPort.class); | 250 | + .register(DefaultVirtualPort.class) |
251 | + .register(RouterId.class) | ||
252 | + .register(TenantRouter.class); | ||
250 | 253 | ||
251 | vPortStore = storageService | 254 | vPortStore = storageService |
252 | .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder() | 255 | .<VirtualPortId, VirtualPort>eventuallyConsistentMapBuilder() |
... | @@ -354,14 +357,48 @@ public class VtnManager implements VtnService { | ... | @@ -354,14 +357,48 @@ public class VtnManager implements VtnService { |
354 | 357 | ||
355 | @Override | 358 | @Override |
356 | public void onOvsDetected(Device device) { | 359 | public void onOvsDetected(Device device) { |
360 | + if (device == null) { | ||
361 | + log.error("The device is null"); | ||
362 | + return; | ||
363 | + } | ||
364 | + if (!mastershipService.isLocalMaster(device.id())) { | ||
365 | + return; | ||
366 | + } | ||
357 | // Create tunnel out flow rules | 367 | // Create tunnel out flow rules |
358 | applyTunnelOut(device, Objective.Operation.ADD); | 368 | applyTunnelOut(device, Objective.Operation.ADD); |
369 | + // apply L3 arp flows | ||
370 | + Iterable<RouterInterface> interfaces = routerInterfaceService | ||
371 | + .getRouterInterfaces(); | ||
372 | + interfaces.forEach(routerInf -> { | ||
373 | + VirtualPort gwPort = virtualPortService.getPort(routerInf.portId()); | ||
374 | + if (gwPort == null) { | ||
375 | + gwPort = VtnData.getPort(vPortStore, routerInf.portId()); | ||
376 | + } | ||
377 | + applyL3ArpFlows(device.id(), gwPort, Objective.Operation.ADD); | ||
378 | + }); | ||
359 | } | 379 | } |
360 | 380 | ||
361 | @Override | 381 | @Override |
362 | public void onOvsVanished(Device device) { | 382 | public void onOvsVanished(Device device) { |
383 | + if (device == null) { | ||
384 | + log.error("The device is null"); | ||
385 | + return; | ||
386 | + } | ||
387 | + if (!mastershipService.isLocalMaster(device.id())) { | ||
388 | + return; | ||
389 | + } | ||
363 | // Remove Tunnel out flow rules | 390 | // Remove Tunnel out flow rules |
364 | applyTunnelOut(device, Objective.Operation.REMOVE); | 391 | applyTunnelOut(device, Objective.Operation.REMOVE); |
392 | + // apply L3 arp flows | ||
393 | + Iterable<RouterInterface> interfaces = routerInterfaceService | ||
394 | + .getRouterInterfaces(); | ||
395 | + interfaces.forEach(routerInf -> { | ||
396 | + VirtualPort gwPort = virtualPortService.getPort(routerInf.portId()); | ||
397 | + if (gwPort == null) { | ||
398 | + gwPort = VtnData.getPort(vPortStore, routerInf.portId()); | ||
399 | + } | ||
400 | + applyL3ArpFlows(device.id(), gwPort, Objective.Operation.REMOVE); | ||
401 | + }); | ||
365 | } | 402 | } |
366 | 403 | ||
367 | @Override | 404 | @Override |
... | @@ -411,13 +448,6 @@ public class VtnManager implements VtnService { | ... | @@ -411,13 +448,6 @@ public class VtnManager implements VtnService { |
411 | } | 448 | } |
412 | 449 | ||
413 | private void applyTunnelOut(Device device, Objective.Operation type) { | 450 | private void applyTunnelOut(Device device, Objective.Operation type) { |
414 | - if (device == null) { | ||
415 | - log.error("The device is null"); | ||
416 | - return; | ||
417 | - } | ||
418 | - if (!mastershipService.isLocalMaster(device.id())) { | ||
419 | - return; | ||
420 | - } | ||
421 | String controllerIp = VtnData.getControllerIpOfSwitch(device); | 451 | String controllerIp = VtnData.getControllerIpOfSwitch(device); |
422 | if (controllerIp == null) { | 452 | if (controllerIp == null) { |
423 | log.error("Can't find controller of device: {}", | 453 | log.error("Can't find controller of device: {}", |
... | @@ -802,6 +832,8 @@ public class VtnManager implements VtnService { | ... | @@ -802,6 +832,8 @@ public class VtnManager implements VtnService { |
802 | programInterfacesSet(interfacesSet, operation); | 832 | programInterfacesSet(interfacesSet, operation); |
803 | } | 833 | } |
804 | } | 834 | } |
835 | + // apply L3 arp flows | ||
836 | + applyL3ArpFlows(null, gwPort, operation); | ||
805 | } | 837 | } |
806 | 838 | ||
807 | @Override | 839 | @Override |
... | @@ -829,6 +861,8 @@ public class VtnManager implements VtnService { | ... | @@ -829,6 +861,8 @@ public class VtnManager implements VtnService { |
829 | gwPort = VtnData.getPort(vPortStore, routerInf.portId()); | 861 | gwPort = VtnData.getPort(vPortStore, routerInf.portId()); |
830 | } | 862 | } |
831 | vPortStore.remove(gwPort.portId()); | 863 | vPortStore.remove(gwPort.portId()); |
864 | + // apply L3 arp flows | ||
865 | + applyL3ArpFlows(null, gwPort, operation); | ||
832 | } | 866 | } |
833 | 867 | ||
834 | @Override | 868 | @Override |
... | @@ -874,6 +908,36 @@ public class VtnManager implements VtnService { | ... | @@ -874,6 +908,36 @@ public class VtnManager implements VtnService { |
874 | }); | 908 | }); |
875 | } | 909 | } |
876 | 910 | ||
911 | + private void applyL3ArpFlows(DeviceId deviceId, VirtualPort gwPort, | ||
912 | + Objective.Operation operation) { | ||
913 | + IpAddress ip = null; | ||
914 | + Iterator<FixedIp> gwIps = gwPort.fixedIps().iterator(); | ||
915 | + if (gwIps.hasNext()) { | ||
916 | + ip = gwIps.next().ip(); | ||
917 | + } | ||
918 | + IpAddress gwIp = ip; | ||
919 | + MacAddress gwMac = gwPort.macAddress(); | ||
920 | + TenantNetwork network = tenantNetworkService | ||
921 | + .getNetwork(gwPort.networkId()); | ||
922 | + if (deviceId != null) { | ||
923 | + // Arp rules | ||
924 | + DriverHandler handler = driverService.createHandler(deviceId); | ||
925 | + arpService.programArpRules(handler, deviceId, gwIp, | ||
926 | + network.segmentationId(), gwMac, | ||
927 | + operation); | ||
928 | + } else { | ||
929 | + Iterable<Device> devices = deviceService.getAvailableDevices(); | ||
930 | + Sets.newHashSet(devices).stream() | ||
931 | + .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> { | ||
932 | + // Arp rules | ||
933 | + DriverHandler handler = driverService.createHandler(d.id()); | ||
934 | + arpService.programArpRules(handler, d.id(), gwIp, | ||
935 | + network.segmentationId(), gwMac, | ||
936 | + operation); | ||
937 | + }); | ||
938 | + } | ||
939 | + } | ||
940 | + | ||
877 | private void applyEastWestL3Flows(Host h, SegmentationId l3vni, | 941 | private void applyEastWestL3Flows(Host h, SegmentationId l3vni, |
878 | Objective.Operation operation) { | 942 | Objective.Operation operation) { |
879 | if (!mastershipService.isLocalMaster(h.location().deviceId())) { | 943 | if (!mastershipService.isLocalMaster(h.location().deviceId())) { |
... | @@ -905,31 +969,53 @@ public class VtnManager implements VtnService { | ... | @@ -905,31 +969,53 @@ public class VtnManager implements VtnService { |
905 | } | 969 | } |
906 | TenantNetwork network = tenantNetworkService | 970 | TenantNetwork network = tenantNetworkService |
907 | .getNetwork(hPort.networkId()); | 971 | .getNetwork(hPort.networkId()); |
972 | + IpAddress dstVmIP = srcIp; | ||
973 | + MacAddress dstVmGwMac = srcVmGwMac; | ||
974 | + TenantId tenantId = hPort.tenantId(); | ||
908 | // Classifier rules | 975 | // Classifier rules |
976 | + if (operation == Objective.Operation.ADD) { | ||
977 | + sendEastWestL3Flows(h, srcVmGwMac, l3vni, srcGwIp, network, | ||
978 | + dstVmIP, dstVmGwMac, operation); | ||
979 | + } else if (operation == Objective.Operation.REMOVE) { | ||
980 | + FloatingIp floatingIp = null; | ||
981 | + Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps(); | ||
982 | + Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps).stream() | ||
983 | + .filter(f -> f.tenantId().equals(tenantId)) | ||
984 | + .collect(Collectors.toSet()); | ||
985 | + for (FloatingIp f : floatingIpSet) { | ||
986 | + IpAddress fixedIp = f.fixedIp(); | ||
987 | + if (fixedIp != null && fixedIp.equals(srcIp)) { | ||
988 | + floatingIp = f; | ||
989 | + break; | ||
990 | + } | ||
991 | + } | ||
992 | + if (floatingIp == null) { | ||
993 | + sendEastWestL3Flows(h, srcVmGwMac, l3vni, srcGwIp, network, | ||
994 | + dstVmIP, dstVmGwMac, operation); | ||
995 | + } | ||
996 | + } | ||
997 | + } | ||
998 | + | ||
999 | + private void sendEastWestL3Flows(Host h, MacAddress srcVmGwMac, | ||
1000 | + SegmentationId l3vni, IpAddress srcGwIp, | ||
1001 | + TenantNetwork network, IpAddress dstVmIP, | ||
1002 | + MacAddress dstVmGwMac, | ||
1003 | + Objective.Operation operation) { | ||
909 | classifierService | 1004 | classifierService |
910 | .programL3InPortClassifierRules(h.location().deviceId(), | 1005 | .programL3InPortClassifierRules(h.location().deviceId(), |
911 | h.location().port(), h.mac(), | 1006 | h.location().port(), h.mac(), |
912 | srcVmGwMac, l3vni, operation); | 1007 | srcVmGwMac, l3vni, operation); |
913 | - classifierService.programArpClassifierRules(h.location().deviceId(), | 1008 | + classifierService |
914 | - h.location().port(), srcGwIp, | 1009 | + .programArpClassifierRules(h.location().deviceId(), |
915 | - network.segmentationId(), | 1010 | + h.location().port(), srcGwIp, |
916 | - operation); | 1011 | + network.segmentationId(), operation); |
917 | - // Arp rules | ||
918 | - if (operation == Objective.Operation.ADD) { | ||
919 | - DriverHandler handler = driverService.createHandler(h.location().deviceId()); | ||
920 | - arpService.programArpRules(handler, h.location().deviceId(), srcGwIp, | ||
921 | - network.segmentationId(), srcVmGwMac, | ||
922 | - operation); | ||
923 | - } | ||
924 | Iterable<Device> devices = deviceService.getAvailableDevices(); | 1012 | Iterable<Device> devices = deviceService.getAvailableDevices(); |
925 | - IpAddress srcArpIp = srcIp; | ||
926 | - MacAddress srcArpGwMac = srcVmGwMac; | ||
927 | Sets.newHashSet(devices).stream() | 1013 | Sets.newHashSet(devices).stream() |
928 | .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> { | 1014 | .filter(d -> Device.Type.SWITCH == d.type()).forEach(d -> { |
929 | // L3FWD rules | 1015 | // L3FWD rules |
930 | - l3ForwardService.programRouteRules(d.id(), l3vni, srcArpIp, | 1016 | + l3ForwardService.programRouteRules(d.id(), l3vni, dstVmIP, |
931 | network.segmentationId(), | 1017 | network.segmentationId(), |
932 | - srcArpGwMac, h.mac(), | 1018 | + dstVmGwMac, h.mac(), |
933 | operation); | 1019 | operation); |
934 | }); | 1020 | }); |
935 | } | 1021 | } |
... | @@ -967,13 +1053,14 @@ public class VtnManager implements VtnService { | ... | @@ -967,13 +1053,14 @@ public class VtnManager implements VtnService { |
967 | // Floating ip BIND | 1053 | // Floating ip BIND |
968 | if (type == VtnRscEvent.Type.FLOATINGIP_BIND) { | 1054 | if (type == VtnRscEvent.Type.FLOATINGIP_BIND) { |
969 | vPortStore.put(fipPort.portId(), fipPort); | 1055 | vPortStore.put(fipPort.portId(), fipPort); |
970 | - applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort, | 1056 | + applyNorthSouthL3Flows(deviceId, false, tenantRouter, host, |
971 | - floaingIp, l3vni, exPort, | 1057 | + vmPort, fipPort, floaingIp, l3vni, |
972 | - Objective.Operation.ADD); | 1058 | + exPort, Objective.Operation.ADD); |
973 | } else if (type == VtnRscEvent.Type.FLOATINGIP_UNBIND) { | 1059 | } else if (type == VtnRscEvent.Type.FLOATINGIP_UNBIND) { |
974 | // Floating ip UNBIND | 1060 | // Floating ip UNBIND |
975 | - applyNorthSouthL3Flows(deviceId, host, vmPort, fipPort, | 1061 | + applyNorthSouthL3Flows(deviceId, false, tenantRouter, host, |
976 | - floaingIp, l3vni, exPort, | 1062 | + vmPort, fipPort, floaingIp, l3vni, |
1063 | + exPort, | ||
977 | Objective.Operation.REMOVE); | 1064 | Objective.Operation.REMOVE); |
978 | vPortStore.remove(fipPort.portId()); | 1065 | vPortStore.remove(fipPort.portId()); |
979 | } | 1066 | } |
... | @@ -981,7 +1068,27 @@ public class VtnManager implements VtnService { | ... | @@ -981,7 +1068,27 @@ public class VtnManager implements VtnService { |
981 | } | 1068 | } |
982 | } | 1069 | } |
983 | 1070 | ||
984 | - private void applyNorthSouthL3Flows(DeviceId deviceId, Host host, | 1071 | + private void sendNorthSouthL3Flows(DeviceId deviceId, FloatingIp floatingIp, |
1072 | + IpAddress dstVmGwIp, | ||
1073 | + MacAddress dstVmGwMac, | ||
1074 | + SegmentationId l3vni, | ||
1075 | + TenantNetwork vmNetwork, | ||
1076 | + VirtualPort vmPort, Host host, | ||
1077 | + Objective.Operation operation) { | ||
1078 | + l3ForwardService | ||
1079 | + .programRouteRules(deviceId, l3vni, floatingIp.fixedIp(), | ||
1080 | + vmNetwork.segmentationId(), dstVmGwMac, | ||
1081 | + vmPort.macAddress(), operation); | ||
1082 | + classifierService.programL3InPortClassifierRules(deviceId, | ||
1083 | + host.location().port(), | ||
1084 | + host.mac(), dstVmGwMac, | ||
1085 | + l3vni, operation); | ||
1086 | + classifierService.programArpClassifierRules(deviceId, host.location() | ||
1087 | + .port(), dstVmGwIp, vmNetwork.segmentationId(), operation); | ||
1088 | + } | ||
1089 | + | ||
1090 | + private void applyNorthSouthL3Flows(DeviceId deviceId, boolean hostFlag, | ||
1091 | + TenantRouter tenantRouter, Host host, | ||
985 | VirtualPort vmPort, VirtualPort fipPort, | 1092 | VirtualPort vmPort, VirtualPort fipPort, |
986 | FloatingIp floatingIp, | 1093 | FloatingIp floatingIp, |
987 | SegmentationId l3vni, Port exPort, | 1094 | SegmentationId l3vni, Port exPort, |
... | @@ -1014,31 +1121,41 @@ public class VtnManager implements VtnService { | ... | @@ -1014,31 +1121,41 @@ public class VtnManager implements VtnService { |
1014 | dnatService.programRules(deviceId, floatingIp.floatingIp(), | 1121 | dnatService.programRules(deviceId, floatingIp.floatingIp(), |
1015 | fGwMac, floatingIp.fixedIp(), | 1122 | fGwMac, floatingIp.fixedIp(), |
1016 | l3vni, operation); | 1123 | l3vni, operation); |
1017 | - l3ForwardService | ||
1018 | - .programRouteRules(deviceId, l3vni, floatingIp.fixedIp(), | ||
1019 | - vmNetwork.segmentationId(), dstVmGwMac, | ||
1020 | - vmPort.macAddress(), operation); | ||
1021 | 1124 | ||
1022 | // L3 uplink traffic flow | 1125 | // L3 uplink traffic flow |
1023 | - classifierService.programL3InPortClassifierRules(deviceId, | ||
1024 | - host.location().port(), | ||
1025 | - host.mac(), dstVmGwMac, | ||
1026 | - l3vni, operation); | ||
1027 | - snatService.programRules(deviceId, l3vni, floatingIp.fixedIp(), | ||
1028 | - fGwMac, exPortMac, | ||
1029 | - floatingIp.floatingIp(), | ||
1030 | - fipNetwork.segmentationId(), operation); | ||
1031 | - classifierService.programArpClassifierRules(deviceId, host.location().port(), | ||
1032 | - dstVmGwIp, vmNetwork.segmentationId(), | ||
1033 | - operation); | ||
1034 | if (operation == Objective.Operation.ADD) { | 1126 | if (operation == Objective.Operation.ADD) { |
1035 | - arpService.programArpRules(handler, deviceId, dstVmGwIp, | 1127 | + sendNorthSouthL3Flows(deviceId, floatingIp, dstVmGwIp, dstVmGwMac, |
1036 | - vmNetwork.segmentationId(), dstVmGwMac, | 1128 | + l3vni, vmNetwork, vmPort, host, operation); |
1037 | - operation); | ||
1038 | l2ForwardService.programLocalOut(deviceId, | 1129 | l2ForwardService.programLocalOut(deviceId, |
1039 | fipNetwork.segmentationId(), | 1130 | fipNetwork.segmentationId(), |
1040 | exPort.number(), fGwMac, operation); | 1131 | exPort.number(), fGwMac, operation); |
1132 | + } else if (operation == Objective.Operation.REMOVE) { | ||
1133 | + if (hostFlag || (!hostFlag | ||
1134 | + && routerInfFlagOfTenantRouter.get(tenantRouter) == null)) { | ||
1135 | + sendNorthSouthL3Flows(deviceId, floatingIp, dstVmGwIp, dstVmGwMac, | ||
1136 | + l3vni, vmNetwork, vmPort, host, operation); | ||
1137 | + } | ||
1138 | + Iterable<FloatingIp> floatingIps = floatingIpService.getFloatingIps(); | ||
1139 | + boolean exPortFlag = true; | ||
1140 | + if (floatingIps != null) { | ||
1141 | + Set<FloatingIp> floatingIpSet = Sets.newHashSet(floatingIps); | ||
1142 | + for (FloatingIp fip : floatingIpSet) { | ||
1143 | + if (fip.fixedIp() != null) { | ||
1144 | + exPortFlag = false; | ||
1145 | + break; | ||
1146 | + } | ||
1147 | + } | ||
1148 | + } | ||
1149 | + if (exPortFlag) { | ||
1150 | + l2ForwardService.programLocalOut(deviceId, | ||
1151 | + fipNetwork.segmentationId(), | ||
1152 | + exPort.number(), fGwMac, operation); | ||
1153 | + } | ||
1041 | } | 1154 | } |
1155 | + snatService.programRules(deviceId, l3vni, floatingIp.fixedIp(), | ||
1156 | + fGwMac, exPortMac, | ||
1157 | + floatingIp.floatingIp(), | ||
1158 | + fipNetwork.segmentationId(), operation); | ||
1042 | } | 1159 | } |
1043 | 1160 | ||
1044 | private Port getExPort(DeviceId deviceId) { | 1161 | private Port getExPort(DeviceId deviceId) { |
... | @@ -1139,7 +1256,7 @@ public class VtnManager implements VtnService { | ... | @@ -1139,7 +1256,7 @@ public class VtnManager implements VtnService { |
1139 | .collect(Collectors.toSet()); | 1256 | .collect(Collectors.toSet()); |
1140 | for (FloatingIp f : floatingIpSet) { | 1257 | for (FloatingIp f : floatingIpSet) { |
1141 | IpAddress fixedIp = f.fixedIp(); | 1258 | IpAddress fixedIp = f.fixedIp(); |
1142 | - if (fixedIp.equals(hostIp)) { | 1259 | + if (fixedIp != null && fixedIp.equals(hostIp)) { |
1143 | floatingIp = f; | 1260 | floatingIp = f; |
1144 | break; | 1261 | break; |
1145 | } | 1262 | } |
... | @@ -1154,8 +1271,9 @@ public class VtnManager implements VtnService { | ... | @@ -1154,8 +1271,9 @@ public class VtnManager implements VtnService { |
1154 | fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(), | 1271 | fipPort = VtnData.getPort(vPortStore, floatingIp.networkId(), |
1155 | floatingIp.floatingIp()); | 1272 | floatingIp.floatingIp()); |
1156 | } | 1273 | } |
1157 | - applyNorthSouthL3Flows(deviceId, host, port, fipPort, floatingIp, | 1274 | + applyNorthSouthL3Flows(deviceId, true, tenantRouter, host, port, |
1158 | - l3vni, exPort, operation); | 1275 | + fipPort, floatingIp, l3vni, exPort, |
1276 | + operation); | ||
1159 | } | 1277 | } |
1160 | } | 1278 | } |
1161 | 1279 | ... | ... |
-
Please register or login to post a comment