mirror of
https://github.com/opennetworkinglab/onos.git
synced 2025-10-17 10:21:52 +02:00
Send GARP packet in case floating ip is associated and gateway node is updated.
Change-Id: I9aa4172bebdc25de5998b3b3123639bce7d865a0
This commit is contained in:
parent
14e87bf5e8
commit
4fa1f5e157
@ -63,6 +63,14 @@ public interface InstancePortService
|
||||
*/
|
||||
InstancePort instancePort(DeviceId deviceId, PortNumber portNumber);
|
||||
|
||||
/**
|
||||
* Returns instance ports with the given device identifier.
|
||||
*
|
||||
* @param deviceId device identifier
|
||||
* @return set of instance ports; empty list if no port exists
|
||||
*/
|
||||
Set<InstancePort> instancePort(DeviceId deviceId);
|
||||
|
||||
/**
|
||||
* Returns all instance ports.
|
||||
*
|
||||
|
@ -225,6 +225,15 @@ public class InstancePortManager
|
||||
.findFirst().orElse(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<InstancePort> instancePort(DeviceId deviceId) {
|
||||
Set<InstancePort> ports = instancePortStore.instancePorts().stream()
|
||||
.filter(port -> port.deviceId().equals(deviceId))
|
||||
.collect(Collectors.toSet());
|
||||
|
||||
return ImmutableSet.copyOf(ports);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<InstancePort> instancePorts() {
|
||||
Set<InstancePort> ports = instancePortStore.instancePorts();
|
||||
|
@ -51,6 +51,7 @@ import org.onosproject.net.packet.PacketContext;
|
||||
import org.onosproject.net.packet.PacketProcessor;
|
||||
import org.onosproject.net.packet.PacketService;
|
||||
import org.onosproject.openstacknetworking.api.Constants;
|
||||
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
|
||||
import org.onosproject.openstacknetworking.api.InstancePort;
|
||||
import org.onosproject.openstacknetworking.api.InstancePortAdminService;
|
||||
import org.onosproject.openstacknetworking.api.InstancePortEvent;
|
||||
@ -60,10 +61,11 @@ import org.onosproject.openstacknetworking.api.OpenstackNetworkAdminService;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackNetworkEvent;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackNetworkListener;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackRouterEvent;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackRouterListener;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackRouterService;
|
||||
import org.onosproject.openstacknetworking.api.PreCommitPortService;
|
||||
import org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil;
|
||||
import org.onosproject.openstacknode.api.OpenstackNode;
|
||||
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
|
||||
import org.onosproject.openstacknode.api.OpenstackNodeListener;
|
||||
@ -71,6 +73,7 @@ import org.onosproject.openstacknode.api.OpenstackNodeService;
|
||||
import org.openstack4j.model.network.ExternalGateway;
|
||||
import org.openstack4j.model.network.IP;
|
||||
import org.openstack4j.model.network.NetFloatingIP;
|
||||
import org.openstack4j.model.network.Network;
|
||||
import org.openstack4j.model.network.Port;
|
||||
import org.openstack4j.model.network.Router;
|
||||
import org.osgi.service.component.ComponentContext;
|
||||
@ -98,7 +101,9 @@ import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.g
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getPropertyValue;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGratuitousArpPacketForFloatingIp;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
|
||||
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.COMPUTE;
|
||||
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
|
||||
import static org.slf4j.LoggerFactory.getLogger;
|
||||
|
||||
@ -124,7 +129,7 @@ public class OpenstackRoutingArpHandler {
|
||||
protected OpenstackNetworkAdminService osNetworkAdminService;
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||
protected OpenstackRouterService osRouterService;
|
||||
protected OpenstackRouterAdminService osRouterAdminService;
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||
protected OpenstackNodeService osNodeService;
|
||||
@ -174,7 +179,7 @@ public class OpenstackRoutingArpHandler {
|
||||
appId = coreService.registerApplication(OPENSTACK_NETWORKING_APP_ID);
|
||||
configService.registerProperties(getClass());
|
||||
localNodeId = clusterService.getLocalNode().id();
|
||||
osRouterService.addListener(osRouterListener);
|
||||
osRouterAdminService.addListener(osRouterListener);
|
||||
osNodeService.addListener(osNodeListener);
|
||||
osNetworkService.addListener(osNetworkListener);
|
||||
instancePortService.addListener(instPortListener);
|
||||
@ -187,7 +192,7 @@ public class OpenstackRoutingArpHandler {
|
||||
protected void deactivate() {
|
||||
packetService.removeProcessor(packetProcessor);
|
||||
instancePortService.removeListener(instPortListener);
|
||||
osRouterService.removeListener(osRouterListener);
|
||||
osRouterAdminService.removeListener(osRouterListener);
|
||||
osNodeService.removeListener(osNodeListener);
|
||||
osNetworkService.removeListener(osNetworkListener);
|
||||
instancePortService.removeListener(instPortListener);
|
||||
@ -221,7 +226,7 @@ public class OpenstackRoutingArpHandler {
|
||||
|
||||
MacAddress targetMac = null;
|
||||
|
||||
NetFloatingIP floatingIP = osRouterService.floatingIps().stream()
|
||||
NetFloatingIP floatingIP = osRouterAdminService.floatingIps().stream()
|
||||
.filter(ip -> ip.getFloatingIpAddress().equals(targetIp.toString()))
|
||||
.findAny().orElse(null);
|
||||
|
||||
@ -359,14 +364,14 @@ public class OpenstackRoutingArpHandler {
|
||||
if (completedGws.contains(gateway)) {
|
||||
if (completedGws.size() > 1) {
|
||||
finalGws.remove(gateway);
|
||||
osRouterService.floatingIps().forEach(fip -> {
|
||||
osRouterAdminService.floatingIps().forEach(fip -> {
|
||||
if (fip.getPortId() != null) {
|
||||
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, false);
|
||||
finalGws.add(gateway);
|
||||
}
|
||||
});
|
||||
}
|
||||
osRouterService.floatingIps().forEach(fip -> {
|
||||
osRouterAdminService.floatingIps().forEach(fip -> {
|
||||
if (fip.getPortId() != null) {
|
||||
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, true);
|
||||
}
|
||||
@ -377,14 +382,14 @@ public class OpenstackRoutingArpHandler {
|
||||
} else {
|
||||
if (!completedGws.contains(gateway)) {
|
||||
finalGws.add(gateway);
|
||||
osRouterService.floatingIps().forEach(fip -> {
|
||||
osRouterAdminService.floatingIps().forEach(fip -> {
|
||||
if (fip.getPortId() != null) {
|
||||
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, false);
|
||||
}
|
||||
});
|
||||
finalGws.remove(gateway);
|
||||
if (completedGws.size() >= 1) {
|
||||
osRouterService.floatingIps().forEach(fip -> {
|
||||
osRouterAdminService.floatingIps().forEach(fip -> {
|
||||
if (fip.getPortId() != null) {
|
||||
setFloatingIpArpRule(fip, fip.getPortId(), finalGws, true);
|
||||
}
|
||||
@ -730,14 +735,14 @@ public class OpenstackRoutingArpHandler {
|
||||
public void event(InstancePortEvent event) {
|
||||
InstancePort instPort = event.subject();
|
||||
|
||||
Set<NetFloatingIP> ips = osRouterService.floatingIps();
|
||||
Set<NetFloatingIP> ips = osRouterAdminService.floatingIps();
|
||||
NetFloatingIP fip = associatedFloatingIp(instPort, ips);
|
||||
Set<OpenstackNode> gateways = osNodeService.completeNodes(GATEWAY);
|
||||
|
||||
switch (event.type()) {
|
||||
case OPENSTACK_INSTANCE_PORT_DETECTED:
|
||||
|
||||
osRouterService.floatingIps().stream()
|
||||
osRouterAdminService.floatingIps().stream()
|
||||
.filter(f -> f.getPortId() != null)
|
||||
.filter(f -> f.getPortId().equals(instPort.portId()))
|
||||
.forEach(f -> setFloatingIpArpRule(f, instPort.portId(), gateways, true));
|
||||
@ -803,16 +808,68 @@ public class OpenstackRoutingArpHandler {
|
||||
case OPENSTACK_NODE_COMPLETE:
|
||||
setDefaultArpRule(osNode, true);
|
||||
setFloatingIpArpRuleForGateway(osNode, true);
|
||||
sendGratuitousArpToSwitch(event.subject(), true);
|
||||
break;
|
||||
case OPENSTACK_NODE_INCOMPLETE:
|
||||
setDefaultArpRule(osNode, false);
|
||||
setFloatingIpArpRuleForGateway(osNode, false);
|
||||
sendGratuitousArpToSwitch(event.subject(), false);
|
||||
break;
|
||||
case OPENSTACK_NODE_REMOVED:
|
||||
sendGratuitousArpToSwitch(event.subject(), false);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendGratuitousArpToSwitch(OpenstackNode gatewayNode, boolean isCompleteCase) {
|
||||
Set<OpenstackNode> completeGws = ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY));
|
||||
|
||||
if (isCompleteCase) {
|
||||
osNodeService.completeNodes(COMPUTE)
|
||||
.stream()
|
||||
.filter(node -> isGwSelectedByComputeNode(completeGws, node, gatewayNode))
|
||||
.forEach(node -> processGratuitousArpPacketForComputeNode(node, gatewayNode));
|
||||
|
||||
} else {
|
||||
Set<OpenstackNode> oldCompleteGws = Sets.newConcurrentHashSet();
|
||||
oldCompleteGws.addAll(ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY)));
|
||||
oldCompleteGws.add(gatewayNode);
|
||||
|
||||
osNodeService.completeNodes(COMPUTE)
|
||||
.stream()
|
||||
.filter(node -> isGwSelectedByComputeNode(oldCompleteGws, node, gatewayNode))
|
||||
.forEach(node -> {
|
||||
OpenstackNode newSelectedGatewayNode = getGwByComputeDevId(completeGws, node.intgBridge());
|
||||
processGratuitousArpPacketForComputeNode(node, newSelectedGatewayNode);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isGwSelectedByComputeNode(Set<OpenstackNode> gws,
|
||||
OpenstackNode computeNode,
|
||||
OpenstackNode gwNode) {
|
||||
return OpenstackNetworkingUtil
|
||||
.getGwByComputeDevId(gws, computeNode.intgBridge())
|
||||
.intgBridge().equals(gwNode.intgBridge());
|
||||
}
|
||||
|
||||
private void processGratuitousArpPacketForComputeNode(OpenstackNode computeNode, OpenstackNode gatewayNode) {
|
||||
instancePortService.instancePort(computeNode.intgBridge()).forEach(instancePort -> {
|
||||
NetFloatingIP floatingIP = OpenstackNetworkingUtil.floatingIpByInstancePort(instancePort,
|
||||
osRouterAdminService);
|
||||
Network network = osNetworkService.network(instancePort.networkId());
|
||||
ExternalPeerRouter externalPeerRouter = OpenstackNetworkingUtil.externalPeerRouterForNetwork(network,
|
||||
osNetworkService, osRouterAdminService);
|
||||
if (floatingIP != null && externalPeerRouter != null) {
|
||||
processGratuitousArpPacketForFloatingIp(
|
||||
floatingIP, instancePort, externalPeerRouter.vlanId(), gatewayNode, packetService);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void setDefaultArpRule(OpenstackNode osNode, boolean install) {
|
||||
switch (getArpMode()) {
|
||||
case ARP_PROXY_MODE:
|
||||
@ -871,7 +928,7 @@ public class OpenstackRoutingArpHandler {
|
||||
install
|
||||
);
|
||||
|
||||
osRouterService.routers().stream()
|
||||
osRouterAdminService.routers().stream()
|
||||
.filter(router -> router.getExternalGatewayInfo() != null)
|
||||
.forEach(router -> setFakeGatewayArpRuleByRouter(router, install));
|
||||
}
|
||||
|
@ -38,6 +38,7 @@ 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.packet.PacketService;
|
||||
import org.onosproject.openstacknetworking.api.Constants;
|
||||
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
|
||||
import org.onosproject.openstacknetworking.api.InstancePort;
|
||||
@ -56,14 +57,10 @@ import org.onosproject.openstacknode.api.OpenstackNode;
|
||||
import org.onosproject.openstacknode.api.OpenstackNodeEvent;
|
||||
import org.onosproject.openstacknode.api.OpenstackNodeListener;
|
||||
import org.onosproject.openstacknode.api.OpenstackNodeService;
|
||||
import org.openstack4j.model.network.ExternalGateway;
|
||||
import org.openstack4j.model.network.NetFloatingIP;
|
||||
import org.openstack4j.model.network.Network;
|
||||
import org.openstack4j.model.network.NetworkType;
|
||||
import org.openstack4j.model.network.Port;
|
||||
import org.openstack4j.model.network.Router;
|
||||
import org.openstack4j.model.network.RouterInterface;
|
||||
import org.openstack4j.model.network.Subnet;
|
||||
import org.openstack4j.openstack.networking.domain.NeutronFloatingIP;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -84,8 +81,11 @@ import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPE
|
||||
import static org.onosproject.openstacknetworking.api.InstancePortEvent.Type.OPENSTACK_INSTANCE_MIGRATION_STARTED;
|
||||
import static org.onosproject.openstacknetworking.api.OpenstackNetworkEvent.Type.OPENSTACK_PORT_PRE_REMOVE;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.associatedFloatingIp;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.externalPeerRouterForNetwork;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByComputeDevId;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.getGwByInstancePort;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.isAssociatedWithVM;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.processGratuitousArpPacketForFloatingIp;
|
||||
import static org.onosproject.openstacknetworking.util.OpenstackNetworkingUtil.swapStaleLocation;
|
||||
import static org.onosproject.openstacknetworking.util.RulePopulatorUtil.buildExtension;
|
||||
import static org.onosproject.openstacknode.api.OpenstackNode.NodeType.GATEWAY;
|
||||
@ -131,6 +131,9 @@ public class OpenstackRoutingFloatingIpHandler {
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||
protected PreCommitPortService preCommitPortService;
|
||||
|
||||
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
|
||||
protected PacketService packetService;
|
||||
|
||||
private final ExecutorService eventExecutor = newSingleThreadExecutor(
|
||||
groupedThreads(this.getClass().getSimpleName(), "event-handler", log));
|
||||
private final OpenstackRouterListener floatingIpListener = new InternalFloatingIpListener();
|
||||
@ -180,15 +183,8 @@ public class OpenstackRoutingFloatingIpHandler {
|
||||
|
||||
Network osNet = osNetworkService.network(instPort.networkId());
|
||||
|
||||
if (osNet == null) {
|
||||
final String errorFormat = ERR_FLOW + "no network(%s) exists";
|
||||
final String error = String.format(errorFormat,
|
||||
floatingIp.getFloatingIpAddress(),
|
||||
instPort.networkId());
|
||||
throw new IllegalStateException(error);
|
||||
}
|
||||
|
||||
ExternalPeerRouter externalPeerRouter = externalPeerRouter(osNet);
|
||||
ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
|
||||
osNetworkService, osRouterAdminService);
|
||||
if (externalPeerRouter == null) {
|
||||
final String errorFormat = ERR_FLOW + "no external peer router found";
|
||||
throw new IllegalStateException(errorFormat);
|
||||
@ -491,36 +487,6 @@ public class OpenstackRoutingFloatingIpHandler {
|
||||
log.trace("Succeeded to set flow rules for upstream on gateway nodes");
|
||||
}
|
||||
|
||||
private ExternalPeerRouter externalPeerRouter(Network network) {
|
||||
if (network == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Subnet subnet = osNetworkService.subnets(network.getId()).stream().findAny().orElse(null);
|
||||
|
||||
if (subnet == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RouterInterface osRouterIface = osRouterAdminService.routerInterfaces().stream()
|
||||
.filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
|
||||
.findAny().orElse(null);
|
||||
if (osRouterIface == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Router osRouter = osRouterAdminService.router(osRouterIface.getId());
|
||||
if (osRouter == null) {
|
||||
return null;
|
||||
}
|
||||
if (osRouter.getExternalGatewayInfo() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
|
||||
return osNetworkService.externalPeerRouter(exGatewayInfo);
|
||||
}
|
||||
|
||||
private void associateFloatingIp(NetFloatingIP osFip) {
|
||||
InstancePort instPort = instancePortService.instancePort(osFip.getPortId());
|
||||
|
||||
@ -533,9 +499,31 @@ public class OpenstackRoutingFloatingIpHandler {
|
||||
// set floating IP rules only if the port is associated to a VM
|
||||
if (!Strings.isNullOrEmpty(instPort.deviceId().toString())) {
|
||||
setFloatingIpRules(osFip, instPort, null, true);
|
||||
processGratuitousArpPacket(osFip, instPort);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void processGratuitousArpPacket(NetFloatingIP floatingIP,
|
||||
InstancePort instancePort) {
|
||||
Set<OpenstackNode> gws = ImmutableSet.copyOf(osNodeService.completeNodes(GATEWAY));
|
||||
|
||||
Network osNet = osNetworkService.network(instancePort.networkId());
|
||||
|
||||
|
||||
OpenstackNode selectedGw = getGwByInstancePort(gws, instancePort);
|
||||
ExternalPeerRouter externalPeerRouter =
|
||||
externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
|
||||
if (externalPeerRouter == null) {
|
||||
log.error("Failed to process GARP packet for floating ip {} because no external peer router found");
|
||||
return;
|
||||
}
|
||||
|
||||
processGratuitousArpPacketForFloatingIp(floatingIP, instancePort, externalPeerRouter.vlanId(),
|
||||
selectedGw, packetService);
|
||||
|
||||
}
|
||||
|
||||
private void disassociateFloatingIp(NetFloatingIP osFip, String portId) {
|
||||
InstancePort instPort = instancePortService.instancePort(portId);
|
||||
|
||||
@ -701,7 +689,8 @@ public class OpenstackRoutingFloatingIpHandler {
|
||||
throw new IllegalStateException(error);
|
||||
}
|
||||
|
||||
ExternalPeerRouter externalPeerRouter = externalPeerRouter(osNet);
|
||||
ExternalPeerRouter externalPeerRouter = externalPeerRouterForNetwork(osNet,
|
||||
osNetworkService, osRouterAdminService);
|
||||
if (externalPeerRouter == null) {
|
||||
final String errorFormat = ERR_FLOW + "no external peer router found";
|
||||
throw new IllegalStateException(errorFormat);
|
||||
@ -776,7 +765,7 @@ public class OpenstackRoutingFloatingIpHandler {
|
||||
|
||||
osPort = osNetworkService.port(fip.getPortId());
|
||||
osNet = osNetworkService.network(osPort.getNetworkId());
|
||||
externalPeerRouter = externalPeerRouter(osNet);
|
||||
externalPeerRouter = externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
|
||||
|
||||
if (externalPeerRouter == null) {
|
||||
final String errorFormat = ERR_FLOW + "no external peer router found";
|
||||
@ -809,7 +798,7 @@ public class OpenstackRoutingFloatingIpHandler {
|
||||
|
||||
osPort = osNetworkService.port(fip.getPortId());
|
||||
osNet = osNetworkService.network(osPort.getNetworkId());
|
||||
externalPeerRouter = externalPeerRouter(osNet);
|
||||
externalPeerRouter = externalPeerRouterForNetwork(osNet, osNetworkService, osRouterAdminService);
|
||||
|
||||
if (externalPeerRouter == null) {
|
||||
final String errorFormat = ERR_FLOW + "no external peer router found";
|
||||
|
@ -42,11 +42,21 @@ import org.apache.sshd.client.channel.ClientChannelEvent;
|
||||
import org.apache.sshd.client.future.OpenFuture;
|
||||
import org.apache.sshd.client.session.ClientSession;
|
||||
import org.apache.sshd.common.util.io.NoCloseInputStream;
|
||||
import org.onlab.packet.ARP;
|
||||
import org.onlab.packet.Ethernet;
|
||||
import org.onlab.packet.Ip4Address;
|
||||
import org.onlab.packet.IpAddress;
|
||||
import org.onlab.packet.MacAddress;
|
||||
import org.onlab.packet.VlanId;
|
||||
import org.onosproject.cfg.ConfigProperty;
|
||||
import org.onosproject.net.DeviceId;
|
||||
import org.onosproject.net.device.DeviceService;
|
||||
import org.onosproject.net.flow.DefaultTrafficTreatment;
|
||||
import org.onosproject.net.flow.TrafficTreatment;
|
||||
import org.onosproject.net.packet.DefaultOutboundPacket;
|
||||
import org.onosproject.net.packet.PacketService;
|
||||
import org.onosproject.openstacknetworking.api.Constants.VnicType;
|
||||
import org.onosproject.openstacknetworking.api.ExternalPeerRouter;
|
||||
import org.onosproject.openstacknetworking.api.InstancePort;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackNetworkService;
|
||||
import org.onosproject.openstacknetworking.api.OpenstackRouterAdminService;
|
||||
@ -63,10 +73,13 @@ import org.openstack4j.core.transport.Config;
|
||||
import org.openstack4j.core.transport.ObjectMapperSingleton;
|
||||
import org.openstack4j.model.ModelEntity;
|
||||
import org.openstack4j.model.common.Identifier;
|
||||
import org.openstack4j.model.network.ExternalGateway;
|
||||
import org.openstack4j.model.network.NetFloatingIP;
|
||||
import org.openstack4j.model.network.Network;
|
||||
import org.openstack4j.model.network.Port;
|
||||
import org.openstack4j.model.network.Router;
|
||||
import org.openstack4j.model.network.RouterInterface;
|
||||
import org.openstack4j.model.network.Subnet;
|
||||
import org.openstack4j.openstack.OSFactory;
|
||||
import org.openstack4j.openstack.networking.domain.NeutronRouterInterface;
|
||||
import org.slf4j.Logger;
|
||||
@ -84,6 +97,7 @@ import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
@ -846,10 +860,125 @@ public final class OpenstackNetworkingUtil {
|
||||
return traceResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the floating ip with supplied instance port.
|
||||
*
|
||||
* @param instancePort instance port
|
||||
* @param osRouterAdminService openstack router admin service
|
||||
* @return floating ip
|
||||
*/
|
||||
public static NetFloatingIP floatingIpByInstancePort(InstancePort instancePort,
|
||||
OpenstackRouterAdminService osRouterAdminService) {
|
||||
return osRouterAdminService.floatingIps().stream()
|
||||
.filter(netFloatingIP -> netFloatingIP.getPortId() != null)
|
||||
.filter(netFloatingIP -> netFloatingIP.getPortId().equals(instancePort.portId()))
|
||||
.findAny().orElse(null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends GARP packet with supplied floating ip information.
|
||||
*
|
||||
* @param floatingIP floating ip
|
||||
* @param instancePort instance port
|
||||
* @param vlanId vlain id
|
||||
* @param gatewayNode gateway node
|
||||
* @param packetService packet service
|
||||
*/
|
||||
public static void processGratuitousArpPacketForFloatingIp(NetFloatingIP floatingIP,
|
||||
InstancePort instancePort,
|
||||
VlanId vlanId,
|
||||
OpenstackNode gatewayNode,
|
||||
PacketService packetService) {
|
||||
Ethernet ethernet = buildGratuitousArpPacket(floatingIP, instancePort, vlanId);
|
||||
|
||||
TrafficTreatment treatment = DefaultTrafficTreatment.builder()
|
||||
.setOutput(gatewayNode.uplinkPortNum()).build();
|
||||
|
||||
packetService.emit(new DefaultOutboundPacket(gatewayNode.intgBridge(), treatment,
|
||||
ByteBuffer.wrap(ethernet.serialize())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the external peer router with supplied network information.
|
||||
*
|
||||
* @param network network
|
||||
* @param osNetworkService openstack network service
|
||||
* @param osRouterAdminService openstack router admin service
|
||||
* @return external peer router
|
||||
*/
|
||||
public static ExternalPeerRouter externalPeerRouterForNetwork(Network network,
|
||||
OpenstackNetworkService osNetworkService,
|
||||
OpenstackRouterAdminService osRouterAdminService) {
|
||||
if (network == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Subnet subnet = osNetworkService.subnets(network.getId()).stream().findAny().orElse(null);
|
||||
|
||||
if (subnet == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
RouterInterface osRouterIface = osRouterAdminService.routerInterfaces().stream()
|
||||
.filter(i -> Objects.equals(i.getSubnetId(), subnet.getId()))
|
||||
.findAny().orElse(null);
|
||||
if (osRouterIface == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Router osRouter = osRouterAdminService.router(osRouterIface.getId());
|
||||
if (osRouter == null) {
|
||||
return null;
|
||||
}
|
||||
if (osRouter.getExternalGatewayInfo() == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ExternalGateway exGatewayInfo = osRouter.getExternalGatewayInfo();
|
||||
return osNetworkService.externalPeerRouter(exGatewayInfo);
|
||||
|
||||
}
|
||||
|
||||
private static boolean isDirectPort(String portName) {
|
||||
return portNamePrefixMap().values().stream().anyMatch(p -> portName.startsWith(p));
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns GARP packet with supplied floating ip and instance port information.
|
||||
*
|
||||
* @param floatingIP floating ip
|
||||
* @param instancePort instance port
|
||||
* @param vlanId vlan id
|
||||
* @return GARP packet
|
||||
*/
|
||||
private static Ethernet buildGratuitousArpPacket(NetFloatingIP floatingIP,
|
||||
InstancePort instancePort,
|
||||
VlanId vlanId) {
|
||||
Ethernet ethernet = new Ethernet();
|
||||
ethernet.setDestinationMACAddress(MacAddress.BROADCAST);
|
||||
ethernet.setSourceMACAddress(instancePort.macAddress());
|
||||
ethernet.setEtherType(Ethernet.TYPE_ARP);
|
||||
ethernet.setVlanID(vlanId.id());
|
||||
|
||||
ARP arp = new ARP();
|
||||
arp.setOpCode(ARP.OP_REPLY);
|
||||
arp.setProtocolType(ARP.PROTO_TYPE_IP);
|
||||
arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
|
||||
|
||||
arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
|
||||
arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
|
||||
|
||||
arp.setSenderHardwareAddress(instancePort.macAddress().toBytes());
|
||||
arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes());
|
||||
|
||||
arp.setSenderProtocolAddress(Ip4Address.valueOf(floatingIP.getFloatingIpAddress()).toInt());
|
||||
arp.setTargetProtocolAddress(Ip4Address.valueOf(floatingIP.getFloatingIpAddress()).toInt());
|
||||
|
||||
ethernet.setPayload(arp);
|
||||
|
||||
return ethernet;
|
||||
}
|
||||
|
||||
/**
|
||||
* Builds up and a complete endpoint URL from gateway node.
|
||||
*
|
||||
|
@ -50,6 +50,11 @@ public class InstancePortServiceAdapter implements InstancePortService {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<InstancePort> instancePort(DeviceId deviceId) {
|
||||
return ImmutableSet.of();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Set<InstancePort> instancePorts() {
|
||||
return ImmutableSet.of();
|
||||
|
Loading…
x
Reference in New Issue
Block a user