use of org.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class TunnellingConnectivityManager method forward.
/**
* Forwards a BGP packet to another connect point.
*
* @param context the packet context of the incoming packet
*/
private void forward(PacketContext context) {
ConnectPoint outputPort = null;
IPv4 ipv4 = (IPv4) context.inPacket().parsed().getPayload();
IpAddress dstAddress = IpAddress.valueOf(ipv4.getDestinationAddress());
if (context.inPacket().receivedFrom().equals(bgpSpeaker.connectPoint())) {
if (bgpSpeaker.peers().contains(dstAddress)) {
Interface intf = interfaceService.getMatchingInterface(dstAddress);
if (intf != null) {
outputPort = intf.connectPoint();
}
}
} else {
Set<Interface> interfaces = interfaceService.getInterfacesByPort(context.inPacket().receivedFrom());
if (interfaces.stream().flatMap(intf -> intf.ipAddressesList().stream()).anyMatch(ia -> ia.ipAddress().equals(dstAddress))) {
outputPort = bgpSpeaker.connectPoint();
}
}
if (outputPort != null) {
TrafficTreatment t = DefaultTrafficTreatment.builder().setOutput(outputPort.port()).build();
OutboundPacket o = new DefaultOutboundPacket(outputPort.deviceId(), t, context.inPacket().unparsed());
packetService.emit(o);
}
}
use of org.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method processDhcpPacketFromServer.
/**
* Build the DHCP offer/ack with proper client port.
*
* @param ethernetPacket the original packet comes from server
* @return new packet which will send to the client
*/
private InternalPacket processDhcpPacketFromServer(PacketContext context, Ethernet ethernetPacket) {
// get dhcp header.
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
UDP udpPacket = (UDP) ipv4Packet.getPayload();
DHCP dhcpPayload = (DHCP) udpPacket.getPayload();
// determine the vlanId of the client host - note that this vlan id
// could be different from the vlan in the packet from the server
Interface clientInterface = getClientInterface(ethernetPacket, dhcpPayload).orElse(null);
if (clientInterface == null) {
log.warn("Cannot find the interface for the DHCP {}", dhcpPayload);
return null;
}
VlanId vlanId;
ConnectPoint inPort = context.inPacket().receivedFrom();
boolean directConnFlag = directlyConnected(dhcpPayload);
DhcpServerInfo foundServerInfo = findServerInfoFromServer(directConnFlag, inPort);
if (foundServerInfo == null) {
log.warn("Cannot find server info for {} server, inPort {}", directConnFlag ? "direct" : "indirect", inPort);
return null;
} else {
if (Dhcp4HandlerUtil.isServerIpEmpty(foundServerInfo)) {
log.warn("Cannot find server info's ipaddress");
return null;
}
}
if (clientInterface.vlanTagged().isEmpty()) {
vlanId = clientInterface.vlan();
} else {
// might be multiple vlan in same interface
vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
}
if (vlanId == null) {
vlanId = VlanId.NONE;
}
etherReply.setVlanID(vlanId.toShort());
etherReply.setSourceMACAddress(clientInterface.mac());
if (!directlyConnected(dhcpPayload)) {
// if client is indirectly connected, try use next hop mac address
MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
HostId hostId = HostId.hostId(macAddress, vlanId);
if (((int) dhcpPayload.getFlags() & 0x8000) == 0x0000) {
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
if (record != null) {
// if next hop can be found, use mac address of next hop
record.nextHop().ifPresent(etherReply::setDestinationMACAddress);
} else {
// otherwise, discard the packet
log.warn("Can't find record for host id {}, discard packet", hostId);
return null;
}
} else {
etherReply.setDestinationMACAddress(MacAddress.BROADCAST);
}
} else {
etherReply.setDestinationMACAddress(dhcpPayload.getClientHardwareAddress());
}
Ip4Address ipFacingClient = getFirstIpFromInterface(clientInterface);
if (directlyConnected(dhcpPayload)) {
// figure out the relay agent IP corresponding to the original request
if (ipFacingClient == null) {
log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. " + "Aborting relay for dhcp packet from server {}", etherReply.getDestinationMAC(), clientInterface.vlan(), ethernetPacket);
return null;
}
// SRC_IP: IP facing client
ipv4Packet.setSourceAddress(ipFacingClient.toInt());
} else {
// Get the IP address of the relay agent
Ip4Address relayAgentIp = foundServerInfo.getRelayAgentIp4(clientInterface.connectPoint().deviceId()).orElse(null);
if (relayAgentIp == null) {
if (ipFacingClient == null) {
log.warn("Cannot determine relay agent interface Ipv4 addr for host {}/{}. " + "Aborting relay for dhcp packet from server for indirect host {}", etherReply.getDestinationMAC(), clientInterface.vlan(), ethernetPacket);
return null;
} else {
// SRC_IP: IP facing client
ipv4Packet.setSourceAddress(ipFacingClient.toInt());
}
} else {
// SRC_IP: relay agent IP
ipv4Packet.setSourceAddress(relayAgentIp.toInt());
}
}
// DST_IP: offered IP
if (((int) dhcpPayload.getFlags() & 0x8000) == 0x0000) {
ipv4Packet.setDestinationAddress(dhcpPayload.getYourIPAddress());
} else {
ipv4Packet.setDestinationAddress(BROADCAST_IP);
}
udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
if (directlyConnected(dhcpPayload)) {
udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
} else {
// TODO Implement component config to support for both L2 and L3 relay
// L2 relay expects destination port to be CLIENT_PORT while L3 relay expects SERVER_PORT
// Currently we only support L2 relay for DHCPv4
udpPacket.setDestinationPort(UDP.DHCP_CLIENT_PORT);
}
udpPacket.setPayload(dhcpPayload);
ipv4Packet.setPayload(udpPacket);
etherReply.setPayload(ipv4Packet);
return InternalPacket.internalPacket(etherReply, clientInterface.connectPoint());
}
use of org.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method writeResponseDhcpRecord.
/**
* Writes DHCP record to the store according to the response DHCP packet (Offer, Ack).
*
* @param ethernet the DHCP packet
* @param dhcpPayload the DHCP payload
*/
private void writeResponseDhcpRecord(Ethernet ethernet, DHCP dhcpPayload) {
Optional<Interface> outInterface = getClientInterface(ethernet, dhcpPayload);
if (!outInterface.isPresent()) {
log.warn("Failed to determine where to send {}", dhcpPayload.getPacketType());
return;
}
Interface outIface = outInterface.get();
ConnectPoint location = outIface.connectPoint();
if (!location.port().hasName()) {
location = translateSwitchPort(location);
}
VlanId vlanId = getVlanIdFromRelayAgentOption(dhcpPayload);
if (vlanId == null) {
vlanId = outIface.vlan();
}
MacAddress macAddress = MacAddress.valueOf(dhcpPayload.getClientHardwareAddress());
HostId hostId = HostId.hostId(macAddress, vlanId);
DhcpRecord record = dhcpRelayStore.getDhcpRecord(hostId).orElse(null);
if (record == null) {
record = new DhcpRecord(HostId.hostId(macAddress, vlanId));
} else {
record = record.clone();
}
record.addLocation(new HostLocation(location, System.currentTimeMillis()));
if (dhcpPayload.getPacketType() == DHCP.MsgType.DHCPACK) {
record.ip4Address(Ip4Address.valueOf(dhcpPayload.getYourIPAddress()));
}
record.ip4Status(dhcpPayload.getPacketType());
record.setDirectlyConnected(directlyConnected(dhcpPayload));
record.updateLastSeen();
dhcpRelayStore.updateDhcpRecord(HostId.hostId(macAddress, vlanId), record);
}
use of org.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method getServerInterface.
/**
* Gets Interface facing to the server for default host.
*
* @param serverInfo server information
* @return the Interface facing to the server; null if not found
*/
private Interface getServerInterface(DhcpServerInfo serverInfo) {
Interface serverInterface = null;
ConnectPoint dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
VlanId dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
if (dhcpServerConnectPoint != null && dhcpConnectVlan != null) {
serverInterface = interfaceService.getInterfacesByPort(dhcpServerConnectPoint).stream().filter(iface -> Dhcp4HandlerUtil.interfaceContainsVlan(iface, dhcpConnectVlan)).findFirst().orElse(null);
} else {
log.warn("DHCP server {} not resolve yet connectPoint {} vlan {}", serverInfo.getDhcpServerIp6(), dhcpServerConnectPoint, dhcpConnectVlan);
}
return serverInterface;
}
use of org.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method processLeaseQueryFromAgent.
/**
* Do a basic routing for a packet from client (used for LQ processing).
*
* @param context the packet context
* @param ethernetPacket the ethernet payload to process
* @return processed packet
*/
private List<InternalPacket> processLeaseQueryFromAgent(PacketContext context, Ethernet ethernetPacket) {
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
DeviceId receivedFromDevice = receivedFrom.deviceId();
// get dhcp header.
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
UDP udpPacket = (UDP) ipv4Packet.getPayload();
DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
Ip4Address relayAgentIp;
Ip4Address clientInterfaceIp = interfaceService.getInterfacesByPort(context.inPacket().receivedFrom()).stream().map(Interface::ipAddressesList).flatMap(Collection::stream).map(InterfaceIpAddress::ipAddress).filter(IpAddress::isIp4).map(IpAddress::getIp4Address).findFirst().orElse(null);
if (clientInterfaceIp == null) {
log.warn("Can't find interface IP for client interface for port {}", context.inPacket().receivedFrom());
return null;
}
boolean isDirectlyConnected = directlyConnected(dhcpPacket);
boolean directConnFlag = directlyConnected(dhcpPacket);
// Multi DHCP Start
List<InternalPacket> internalPackets = new ArrayList<>();
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
List<DhcpServerInfo> copyServerInfoList = new ArrayList<>(serverInfoList);
for (DhcpServerInfo serverInfo : copyServerInfoList) {
// get dhcp header.
etherReply = (Ethernet) ethernetPacket.clone();
ipv4Packet = (IPv4) etherReply.getPayload();
udpPacket = (UDP) ipv4Packet.getPayload();
dhcpPacket = (DHCP) udpPacket.getPayload();
if (!checkDhcpServerConnPt(directConnFlag, serverInfo)) {
log.warn("Can't get server connect point, ignore");
continue;
}
DhcpServerInfo newServerInfo = getHostInfoForServerInfo(serverInfo, serverInfoList);
if (newServerInfo == null) {
log.warn("Can't get server interface with host info resolved, ignore");
continue;
}
Interface serverInterface = getServerInterface(newServerInfo);
if (serverInterface == null) {
log.warn("Can't get server interface, ignore");
continue;
}
Ip4Address ipFacingServer = getFirstIpFromInterface(serverInterface);
MacAddress macFacingServer = serverInterface.mac();
if (ipFacingServer == null || macFacingServer == null) {
log.warn("No IP address for server Interface {}", serverInterface);
continue;
}
etherReply.setSourceMACAddress(macFacingServer);
etherReply.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
etherReply.setVlanID(newServerInfo.getDhcpConnectVlan().get().toShort());
ipv4Packet.setSourceAddress(ipFacingServer.toInt());
ipv4Packet.setDestinationAddress(newServerInfo.getDhcpServerIp4().get().toInt());
if (isDirectlyConnected) {
// set default info and replace with indirect if available later on.
if (newServerInfo.getDhcpConnectMac().isPresent()) {
etherReply.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
}
if (newServerInfo.getDhcpConnectVlan().isPresent()) {
etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
}
if (learnRouteFromLeasequery) {
relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
// Sets relay agent IP
int effectiveRelayAgentIp = relayAgentIp != null ? relayAgentIp.toInt() : clientInterfaceIp.toInt();
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
}
} else {
if (!newServerInfo.getDhcpServerIp4().isPresent()) {
// do nothing
} else if (!newServerInfo.getDhcpConnectMac().isPresent()) {
continue;
} else if (learnRouteFromLeasequery) {
relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
// Sets relay agent IP
int effectiveRelayAgentIp = relayAgentIp != null ? relayAgentIp.toInt() : clientInterfaceIp.toInt();
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
log.debug("Relay Agent IP {}", relayAgentIp);
}
log.trace("Indirect");
}
// Remove broadcast flag
dhcpPacket.setFlags((short) 0);
udpPacket.setPayload(dhcpPacket);
// As a DHCP relay, the source port should be server port( instead
// of client port.
udpPacket.setSourcePort(UDP.DHCP_SERVER_PORT);
udpPacket.setDestinationPort(UDP.DHCP_SERVER_PORT);
ipv4Packet.setPayload(udpPacket);
ipv4Packet.setTtl((byte) 64);
etherReply.setPayload(ipv4Packet);
udpPacket.resetChecksum();
// //return etherReply;
InternalPacket internalPacket = InternalPacket.internalPacket(etherReply, newServerInfo.getDhcpServerConnectPoint().get());
internalPackets.add(internalPacket);
}
log.debug("num of processLeaseQueryFromAgent packets to send is: {}", internalPackets.size());
return internalPackets;
}
Aggregations