use of org.onosproject.openstacknode.api.OpenstackNode in project onos by opennetworkinglab.
the class OpenstackNetworkManager method deriveExternalPeerRouterMac.
@Override
public void deriveExternalPeerRouterMac(ExternalGateway externalGateway, Router router, VlanId vlanId) {
log.info("deriveExternalPeerRouterMac called");
IpAddress sourceIp = getExternalGatewaySourceIp(externalGateway, router);
IpAddress targetIp = getExternalPeerRouterIp(externalGateway);
if (sourceIp == null || targetIp == null) {
log.warn("Failed to derive external router mac address because " + "source IP {} or target IP {} is null", sourceIp, targetIp);
return;
}
ExternalPeerRouter peerRouter = osNetworkStore.externalPeerRouter(targetIp.toString());
// MAC address has been derived
if (peerRouter != null && !peerRouter.macAddress().equals(MacAddress.NONE)) {
return;
}
MacAddress sourceMac = Constants.DEFAULT_GATEWAY_MAC;
Ethernet ethRequest = ARP.buildArpRequest(sourceMac.toBytes(), sourceIp.toOctets(), targetIp.toOctets(), vlanId.id());
if (osNodeService.completeNodes(GATEWAY).isEmpty()) {
log.warn("There's no complete gateway");
return;
}
OpenstackNode gatewayNode = osNodeService.completeNodes(GATEWAY).stream().findFirst().orElse(null);
if (gatewayNode == null) {
return;
}
if (gatewayNode.uplinkPortNum() == null) {
log.warn("There's no uplink port for gateway node {}", gatewayNode.toString());
return;
}
TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(gatewayNode.uplinkPortNum()).build();
packetService.emit(new DefaultOutboundPacket(gatewayNode.intgBridge(), treatment, ByteBuffer.wrap(ethRequest.serialize())));
ExternalPeerRouter derivedRouter = DefaultExternalPeerRouter.builder().ipAddress(targetIp).macAddress(MacAddress.NONE).vlanId(vlanId).build();
osNetworkStore.createExternalPeerRouter(derivedRouter);
log.info("Initializes external peer router map with peer router IP {}", targetIp.toString());
}
use of org.onosproject.openstacknode.api.OpenstackNode in project onos by opennetworkinglab.
the class OpenstackRoutingArpHandler method processArpPacket.
private void processArpPacket(PacketContext context, Ethernet ethernet) {
ARP arp = (ARP) ethernet.getPayload();
if (arp.getOpCode() == ARP.OP_REQUEST && ARP_PROXY_MODE.equals(getArpMode())) {
if (log.isTraceEnabled()) {
log.trace("ARP request received from {} for {}", Ip4Address.valueOf(arp.getSenderProtocolAddress()).toString(), Ip4Address.valueOf(arp.getTargetProtocolAddress()).toString());
}
IpAddress targetIp = Ip4Address.valueOf(arp.getTargetProtocolAddress());
MacAddress targetMac = null;
NetFloatingIP floatingIP = osRouterAdminService.floatingIps().stream().filter(ip -> ip.getFloatingIpAddress().equals(targetIp.toString())).findAny().orElse(null);
// In case target ip is for associated floating ip, sets target mac to vm's.
if (floatingIP != null && floatingIP.getPortId() != null) {
InstancePort instPort = instancePortService.instancePort(floatingIP.getPortId());
if (instPort == null) {
log.trace("Unknown target ARP request for {}, ignore it", targetIp);
return;
} else {
targetMac = instPort.macAddress();
}
OpenstackNode gw = getGwByInstancePort(osNodeService.completeNodes(GATEWAY), instPort);
if (gw == null) {
return;
}
// if the ARP packet_in received from non-relevant GWs, we simply ignore it
if (!Objects.equals(gw.intgBridge(), context.inPacket().receivedFrom().deviceId())) {
return;
}
}
if (isExternalGatewaySourceIp(targetIp)) {
targetMac = Constants.DEFAULT_GATEWAY_MAC;
}
if (targetMac == null) {
log.trace("Unknown target ARP request for {}, ignore it", targetIp);
return;
}
Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(), targetMac, ethernet);
TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(context.inPacket().receivedFrom().port()).build();
packetService.emit(new DefaultOutboundPacket(context.inPacket().receivedFrom().deviceId(), treatment, ByteBuffer.wrap(ethReply.serialize())));
context.block();
}
if (arp.getOpCode() == ARP.OP_REPLY) {
ConnectPoint cp = context.inPacket().receivedFrom();
PortNumber receivedPortNum = cp.port();
IpAddress spa = Ip4Address.valueOf(arp.getSenderProtocolAddress());
MacAddress sha = MacAddress.valueOf(arp.getSenderHardwareAddress());
log.debug("ARP reply ip: {}, mac: {}", spa, sha);
try {
Set<String> extRouterIps = osNetworkService.externalPeerRouters().stream().map(r -> r.ipAddress().toString()).collect(Collectors.toSet());
// if SPA is NOT contained in existing external router IP set, we ignore it
if (!extRouterIps.contains(spa.toString())) {
return;
}
OpenstackNode node = osNodeService.node(cp.deviceId());
if (node == null) {
return;
}
// we only handles the ARP-Reply message received by gateway node
if (node.type() != GATEWAY) {
return;
}
if (receivedPortNum.equals(node.uplinkPortNum())) {
osNetworkAdminService.updateExternalPeerRouterMac(spa, sha);
}
} catch (Exception e) {
log.error("Exception occurred because of {}", e);
}
}
}
use of org.onosproject.openstacknode.api.OpenstackNode in project onos by opennetworkinglab.
the class OpenstackRoutingFloatingIpHandler method setDownstreamExternalRulesHelper.
private void setDownstreamExternalRulesHelper(NetFloatingIP floatingIp, Network osNet, InstancePort instPort, ExternalPeerRouter externalPeerRouter, Set<OpenstackNode> gateways, boolean install) {
OpenstackNode cNode = osNodeService.node(instPort.deviceId());
Type netType = osNetworkService.networkType(osNet.getId());
if (cNode == null) {
final String error = String.format("Cannot find openstack node for device %s", instPort.deviceId());
throw new IllegalStateException(error);
}
if (netType == VXLAN && cNode.dataIp() == null) {
final String errorFormat = ERR_FLOW + "VXLAN mode is not ready for %s";
final String error = String.format(errorFormat, floatingIp, cNode.hostname());
throw new IllegalStateException(error);
}
if (netType == GRE && cNode.dataIp() == null) {
final String errorFormat = ERR_FLOW + "GRE mode is not ready for %s";
final String error = String.format(errorFormat, floatingIp, cNode.hostname());
throw new IllegalStateException(error);
}
if (netType == GENEVE && cNode.dataIp() == null) {
final String errorFormat = ERR_FLOW + "GENEVE mode is not ready for %s";
final String error = String.format(errorFormat, floatingIp, cNode.hostname());
throw new IllegalStateException(error);
}
if (netType == VLAN && cNode.vlanIntf() == null) {
final String errorFormat = ERR_FLOW + "VLAN mode is not ready for %s";
final String error = String.format(errorFormat, floatingIp, cNode.hostname());
throw new IllegalStateException(error);
}
IpAddress floating = IpAddress.valueOf(floatingIp.getFloatingIpAddress());
OpenstackNode selectedGatewayNode = getGwByComputeDevId(gateways, instPort.deviceId());
if (selectedGatewayNode == null) {
final String errorFormat = ERR_FLOW + "no gateway node selected";
throw new IllegalStateException(errorFormat);
}
TrafficSelector.Builder externalSelectorBuilder = DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV4).matchInPort(selectedGatewayNode.uplinkPortNum()).matchIPDst(floating.toIpPrefix());
TrafficTreatment.Builder externalTreatmentBuilder = DefaultTrafficTreatment.builder().setEthSrc(Constants.DEFAULT_GATEWAY_MAC).setEthDst(instPort.macAddress()).setIpDst(instPort.ipAddress().getIp4Address());
if (!externalPeerRouter.vlanId().equals(VlanId.NONE)) {
externalSelectorBuilder.matchVlanId(externalPeerRouter.vlanId()).build();
externalTreatmentBuilder.popVlan();
}
switch(netType) {
case VXLAN:
case GRE:
case GENEVE:
PortNumber portNum = tunnelPortNumByNetId(instPort.networkId(), osNetworkService, selectedGatewayNode);
externalTreatmentBuilder.setTunnelId(Long.valueOf(osNet.getProviderSegID())).extension(buildExtension(deviceService, selectedGatewayNode.intgBridge(), cNode.dataIp().getIp4Address()), selectedGatewayNode.intgBridge()).setOutput(portNum);
break;
case VLAN:
externalTreatmentBuilder.pushVlan().setVlanId(VlanId.vlanId(osNet.getProviderSegID())).setOutput(selectedGatewayNode.vlanPortNum());
break;
default:
final String error = String.format(ERR_UNSUPPORTED_NET_TYPE, osNet.getNetworkType());
throw new IllegalStateException(error);
}
osFlowRuleService.setRule(appId, selectedGatewayNode.intgBridge(), externalSelectorBuilder.build(), externalTreatmentBuilder.build(), PRIORITY_FLOATING_EXTERNAL, GW_COMMON_TABLE, install);
setArpRule(floatingIp, instPort.macAddress(), selectedGatewayNode, install);
}
use of org.onosproject.openstacknode.api.OpenstackNode in project onos by opennetworkinglab.
the class OpenstackSwitchingArpHandler method setRemoteArpTreatmentForVlan.
// a helper method
private void setRemoteArpTreatmentForVlan(TrafficSelector selector, InstancePort port, short arpOp, boolean install) {
int priority;
if (arpOp == ARP.OP_REQUEST) {
priority = PRIORITY_ARP_REQUEST_RULE;
} else if (arpOp == ARP.OP_REPLY) {
priority = PRIORITY_ARP_REPLY_RULE;
} else {
// if ARP op does not match with any operation mode, we simply
// configure the ARP request rule priority
priority = PRIORITY_ARP_REQUEST_RULE;
}
for (OpenstackNode remoteNode : osNodeService.completeNodes(COMPUTE)) {
if (!remoteNode.intgBridge().equals(port.deviceId()) && remoteNode.vlanIntf() != null) {
TrafficTreatment treatmentToRemote = DefaultTrafficTreatment.builder().setOutput(remoteNode.vlanPortNum()).build();
osFlowRuleService.setRule(appId, remoteNode.intgBridge(), selector, treatmentToRemote, priority, ARP_TABLE, install);
}
}
}
use of org.onosproject.openstacknode.api.OpenstackNode in project onos by opennetworkinglab.
the class OpenstackSwitchingArpHandler method setRemoteArpRequestRuleForTunnel.
/**
* Installs flow rules at remote node to match ARP request packets for Tunnel.
*
* @param port instance port
* @param install installation flag
*/
private void setRemoteArpRequestRuleForTunnel(InstancePort port, boolean install) {
OpenstackNode localNode = osNodeService.node(port.deviceId());
String segId = osNetworkService.segmentId(port.networkId());
TrafficSelector selector = DefaultTrafficSelector.builder().matchEthType(EthType.EtherType.ARP.ethType().toShort()).matchArpOp(ARP.OP_REQUEST).matchArpTpa(port.ipAddress().getIp4Address()).matchTunnelId(Long.parseLong(segId)).build();
setRemoteArpTreatmentForTunnel(selector, port, localNode, install);
}
Aggregations