use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method processDhcpPacketFromClient.
/**
* Build the DHCP discover/request packet with gateway IP(unicast packet).
*
* @param context the packet context
* @param ethernetPacket the ethernet payload to process
* @return processed packet
*/
private List<InternalPacket> processDhcpPacketFromClient(PacketContext context, Ethernet ethernetPacket, Set<Interface> clientInterfaces) {
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
DeviceId receivedFromDevice = receivedFrom.deviceId();
Ip4Address relayAgentIp = null;
relayAgentIp = Dhcp4HandlerUtil.getRelayAgentIPv4Address(clientInterfaces);
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
if (relayAgentIp == null || relayAgentMac == null) {
log.warn("Missing DHCP relay agent interface Ipv4 addr config for " + "packet from client on port: {}. Aborting packet processing", clientInterfaces.iterator().next().connectPoint());
return Lists.newArrayList();
}
log.debug("Multi DHCP V4 processDhcpPacketFromClient on port {}", clientInterfaces.iterator().next().connectPoint());
// get dhcp header.
Ethernet etherReply = (Ethernet) ethernetPacket.clone();
IPv4 ipv4Packet = (IPv4) etherReply.getPayload();
UDP udpPacket = (UDP) ipv4Packet.getPayload();
DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
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 Lists.newArrayList();
}
boolean isDirectlyConnected = directlyConnected(dhcpPacket);
boolean directConnFlag = directlyConnected(dhcpPacket);
// Multi DHCP Start
ConnectPoint clientConnectionPoint = context.inPacket().receivedFrom();
VlanId vlanIdInUse = VlanId.vlanId(ethernetPacket.getVlanID());
Interface clientInterface = interfaceService.getInterfacesByPort(clientConnectionPoint).stream().filter(iface -> Dhcp4HandlerUtil.interfaceContainsVlan(iface, vlanIdInUse)).findFirst().orElse(null);
List<InternalPacket> internalPackets = new ArrayList<>();
List<DhcpServerInfo> serverInfoList = findValidServerInfo(directConnFlag);
List<DhcpServerInfo> copyServerInfoList = new ArrayList<DhcpServerInfo>(serverInfoList);
boolean serverFound = false;
for (DhcpServerInfo serverInfo : copyServerInfoList) {
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.debug("Can't get server interface with host info resolved, ignore serverInfo {} serverInfoList {}", serverInfo, serverInfoList);
continue;
}
Interface serverInterface = getServerInterface(newServerInfo);
if (serverInterface == null) {
log.debug("Can't get server interface, ignore for serverInfo {}, serverInfoList {}", serverInfo, serverInfoList);
continue;
}
Ip4Address ipFacingServer = getFirstIpFromInterface(serverInterface);
MacAddress macFacingServer = serverInterface.mac();
log.debug("Interfacing server {} Mac : {} ", ipFacingServer, macFacingServer);
if (ipFacingServer == null || macFacingServer == null) {
log.debug("No IP address for server Interface {}", serverInterface);
continue;
}
serverFound = true;
log.debug("Server Info Found {}", serverInfo.getDhcpConnectMac());
etherReply.setSourceMACAddress(macFacingServer);
// 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(newServerInfo.getDhcpConnectVlan().get().toShort());
}
ipv4Packet.setSourceAddress(ipFacingServer.toInt());
ipv4Packet.setDestinationAddress(newServerInfo.getDhcpServerIp4().get().toInt());
log.debug("Directly connected {}", isDirectlyConnected);
log.debug("DHCP server IP: {}", newServerInfo.getDhcpServerIp4().get());
if (isDirectlyConnected) {
log.debug("Default DHCP server IP: {}", newServerInfo.getDhcpServerIp4().get());
if (newServerInfo.getDhcpConnectMac().isPresent()) {
etherReply.setDestinationMACAddress(newServerInfo.getDhcpConnectMac().get());
}
if (newServerInfo.getDhcpConnectVlan().isPresent()) {
etherReply.setVlanID(newServerInfo.getDhcpConnectVlan().get().toShort());
}
ipv4Packet.setDestinationAddress(newServerInfo.getDhcpServerIp4().get().toInt());
ConnectPoint inPort = context.inPacket().receivedFrom();
VlanId vlanId = VlanId.vlanId(ethernetPacket.getVlanID());
// add connected in port and vlan
CircuitId cid = new CircuitId(inPort.toString(), vlanId);
byte[] circuitId = cid.serialize();
DhcpOption circuitIdSubOpt = new DhcpOption();
circuitIdSubOpt.setCode(CIRCUIT_ID.getValue()).setLength((byte) circuitId.length).setData(circuitId);
DhcpRelayAgentOption newRelayAgentOpt = new DhcpRelayAgentOption();
newRelayAgentOpt.setCode(OptionCode_CircuitID.getValue());
newRelayAgentOpt.addSubOption(circuitIdSubOpt);
// Removes END option first
List<DhcpOption> options = dhcpPacket.getOptions().stream().filter(opt -> opt.getCode() != OptionCode_END.getValue()).collect(Collectors.toList());
// push relay agent option
options.add(newRelayAgentOpt);
// make sure option 255(End) is the last option
DhcpOption endOption = new DhcpOption();
endOption.setCode(OptionCode_END.getValue());
options.add(endOption);
dhcpPacket.setOptions(options);
relayAgentIp = serverInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
// Sets relay agent IP
int effectiveRelayAgentIp = relayAgentIp != null ? relayAgentIp.toInt() : clientInterfaceIp.toInt();
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
log.debug("In Default, Relay Agent IP {}", effectiveRelayAgentIp);
} else {
if (!newServerInfo.getDhcpServerIp4().isPresent()) {
// do nothing
} else if (!newServerInfo.getDhcpConnectMac().isPresent()) {
continue;
} else {
relayAgentIp = newServerInfo.getRelayAgentIp4(receivedFromDevice).orElse(null);
// Sets relay agent IP
int effectiveRelayAgentIp = relayAgentIp != null ? relayAgentIp.toInt() : clientInterfaceIp.toInt();
Ip4Address effectiveRealRealyAgentIP = relayAgentIp != null ? relayAgentIp : clientInterfaceIp;
dhcpPacket.setGatewayIPAddress(effectiveRelayAgentIp);
ipv4Packet.setSourceAddress(effectiveRealRealyAgentIP.toInt());
log.debug("Source IP address set as relay agent IP with value: {}", effectiveRealRealyAgentIP);
}
}
// 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);
InternalPacket internalPacket = InternalPacket.internalPacket(etherReply, serverInfo.getDhcpServerConnectPoint().get());
internalPackets.add(internalPacket);
}
if (!serverFound) {
log.warn("ProcessDhcp4PacketFromClient No Server Found");
}
return internalPackets;
}
use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method removeRelayAgentOption.
/**
* Removes DHCP relay agent information option (option 82) from DHCP payload.
* Also reset giaddr to 0
*
* @param ethPacket the Ethernet packet to be processed
* @return Ethernet packet processed
*/
private Ethernet removeRelayAgentOption(Ethernet ethPacket) {
Ethernet ethernet = (Ethernet) ethPacket.duplicate();
IPv4 ipv4 = (IPv4) ethernet.getPayload();
UDP udp = (UDP) ipv4.getPayload();
DHCP dhcpPayload = (DHCP) udp.getPayload();
// removes relay agent information option
List<DhcpOption> options = dhcpPayload.getOptions();
options = options.stream().filter(option -> option.getCode() != OptionCode_CircuitID.getValue()).collect(Collectors.toList());
dhcpPayload.setOptions(options);
dhcpPayload.setGatewayIPAddress(0);
udp.setPayload(dhcpPayload);
ipv4.setPayload(udp);
ethernet.setPayload(ipv4);
return ethernet;
}
use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class IcmpHandler method sendIcmpResponse.
private void sendIcmpResponse(Ethernet icmpRequest, ConnectPoint outport) {
Ethernet icmpReplyEth = new Ethernet();
IPv4 icmpRequestIpv4 = (IPv4) icmpRequest.getPayload();
IPv4 icmpReplyIpv4 = new IPv4();
int destAddress = icmpRequestIpv4.getDestinationAddress();
icmpReplyIpv4.setDestinationAddress(icmpRequestIpv4.getSourceAddress());
icmpReplyIpv4.setSourceAddress(destAddress);
icmpReplyIpv4.setTtl((byte) 64);
icmpReplyIpv4.setChecksum((short) 0);
ICMP icmpReply = new ICMP();
icmpReply.setPayload(((ICMP) icmpRequestIpv4.getPayload()).getPayload());
icmpReply.setIcmpType(ICMP.TYPE_ECHO_REPLY);
icmpReply.setIcmpCode(ICMP.CODE_ECHO_REPLY);
icmpReply.setChecksum((short) 0);
icmpReplyIpv4.setPayload(icmpReply);
icmpReplyEth.setPayload(icmpReplyIpv4);
icmpReplyEth.setEtherType(Ethernet.TYPE_IPV4);
icmpReplyEth.setDestinationMACAddress(icmpRequest.getSourceMACAddress());
icmpReplyEth.setSourceMACAddress(icmpRequest.getDestinationMACAddress());
icmpReplyEth.setVlanID(icmpRequest.getVlanID());
sendPacketOut(outport, icmpReplyEth);
}
use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class IcmpHandler method processPacketIn.
private void processPacketIn(InboundPacket pkt) {
boolean ipMatches = false;
Ethernet ethernet = pkt.parsed();
IPv4 ipv4 = (IPv4) ethernet.getPayload();
ConnectPoint connectPoint = pkt.receivedFrom();
IpAddress destIpAddress = IpAddress.valueOf(ipv4.getDestinationAddress());
Interface targetInterface = interfaceService.getMatchingInterface(destIpAddress);
if (targetInterface == null) {
log.trace("No matching interface for {}", destIpAddress);
return;
}
for (InterfaceIpAddress interfaceIpAddress : targetInterface.ipAddressesList()) {
if (interfaceIpAddress.ipAddress().equals(destIpAddress)) {
ipMatches = true;
break;
}
}
if (((ICMP) ipv4.getPayload()).getIcmpType() == ICMP.TYPE_ECHO_REQUEST && ipMatches) {
sendIcmpResponse(ethernet, connectPoint);
}
}
use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class OpenstackRoutingSnatHandler method setStatelessSnatUpstreamRules.
private void setStatelessSnatUpstreamRules(String segmentId, Type networkType, IpAddress externalIp, ExternalPeerRouter externalPeerRouter, TpPort patPort, InboundPacket packetIn) {
IPv4 iPacket = (IPv4) packetIn.parsed().getPayload();
TrafficSelector.Builder sBuilder = DefaultTrafficSelector.builder().matchEthType(Ethernet.TYPE_IPV4).matchIPProtocol(iPacket.getProtocol()).matchIPSrc(IpPrefix.valueOf(iPacket.getSourceAddress(), VM_PREFIX)).matchIPDst(IpPrefix.valueOf(iPacket.getDestinationAddress(), VM_PREFIX));
TrafficTreatment.Builder tBuilder = DefaultTrafficTreatment.builder();
switch(networkType) {
case VXLAN:
case GRE:
case GENEVE:
sBuilder.matchTunnelId(Long.parseLong(segmentId));
break;
case VLAN:
sBuilder.matchVlanId(VlanId.vlanId(segmentId));
tBuilder.popVlan();
break;
default:
final String error = String.format("%s %s", ERR_UNSUPPORTED_NET_TYPE, networkType.toString());
throw new IllegalStateException(error);
}
switch(iPacket.getProtocol()) {
case IPv4.PROTOCOL_TCP:
TCP tcpPacket = (TCP) iPacket.getPayload();
sBuilder.matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort())).matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort()));
tBuilder.setTcpSrc(patPort).setEthDst(externalPeerRouter.macAddress());
break;
case IPv4.PROTOCOL_UDP:
UDP udpPacket = (UDP) iPacket.getPayload();
sBuilder.matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort())).matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));
tBuilder.setUdpSrc(patPort).setEthDst(externalPeerRouter.macAddress());
break;
default:
log.debug("Unsupported IPv4 protocol {}");
break;
}
if (!externalPeerRouter.vlanId().equals(VlanId.NONE)) {
tBuilder.pushVlan().setVlanId(externalPeerRouter.vlanId());
}
tBuilder.setIpSrc(externalIp);
osNodeService.completeNodes(GATEWAY).forEach(gNode -> {
TrafficTreatment.Builder tmpBuilder = DefaultTrafficTreatment.builder(tBuilder.build());
tmpBuilder.setOutput(gNode.uplinkPortNum());
osFlowRuleService.setRule(appId, gNode.intgBridge(), sBuilder.build(), tmpBuilder.build(), PRIORITY_SNAT_RULE, GW_COMMON_TABLE, true);
});
}
Aggregations