use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class PimPacketHandler method processPacket.
/**
* Sanitize and process the packet.
* TODO: replace ConnectPoint with PIMInterface when PIMInterface has been added.
*
* @param ethPkt the packet starting with the Ethernet header.
* @param pimi the PIM Interface the packet arrived on.
*/
public void processPacket(Ethernet ethPkt, PimInterface pimi) {
checkNotNull(ethPkt);
checkNotNull(pimi);
// Sanitize the ethernet header to ensure it is IPv4. IPv6 we'll deal with later
if (ethPkt.getEtherType() != Ethernet.TYPE_IPV4) {
return;
}
// Get the IP header
IPv4 ip = (IPv4) ethPkt.getPayload();
if (ip.getProtocol() != IPv4.PROTOCOL_PIM) {
return;
}
// Get the address of our the neighbor that sent this packet to us.
IpAddress nbraddr = IpAddress.valueOf(ip.getDestinationAddress());
if (log.isTraceEnabled()) {
log.trace("Packet {} received on port {}", nbraddr, pimi);
}
// Get the PIM header
PIM pim = (PIM) ip.getPayload();
checkNotNull(pim);
// Process the pim packet
switch(pim.getPimMsgType()) {
case PIM.TYPE_HELLO:
pimi.processHello(ethPkt);
break;
case PIM.TYPE_JOIN_PRUNE_REQUEST:
pimi.processJoinPrune(ethPkt);
log.debug("Received a PIM Join/Prune message");
break;
default:
log.debug("Received unsupported PIM type: {}", pim.getPimMsgType());
break;
}
}
use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class DirectHostManager method handle.
private boolean handle(Ethernet eth) {
checkNotNull(eth);
// skip them.
if (!enabled || (eth.getEtherType() != Ethernet.TYPE_IPV6 && eth.getEtherType() != Ethernet.TYPE_IPV4)) {
return false;
}
// According to the type we set the destIp.
IpAddress dstIp;
if (eth.getEtherType() == Ethernet.TYPE_IPV4) {
IPv4 ip = (IPv4) eth.getPayload();
dstIp = IpAddress.valueOf(ip.getDestinationAddress());
} else {
IPv6 ip = (IPv6) eth.getPayload();
dstIp = IpAddress.valueOf(INET6, ip.getDestinationAddress());
}
// Looking for a candidate output port.
Interface egressInterface = interfaceService.getMatchingInterface(dstIp);
if (egressInterface == null) {
log.info("No egress interface found for {}", dstIp);
return false;
}
// Looking for the destination mac.
Optional<Host> host = hostService.getHostsByIp(dstIp).stream().filter(h -> h.location().equals(egressInterface.connectPoint())).filter(h -> h.vlan().equals(egressInterface.vlan())).findAny();
// and we queue the packets waiting for a destination.
if (host.isPresent()) {
transformAndSend((IP) eth.getPayload(), eth.getEtherType(), egressInterface, host.get().mac());
} else {
hostService.startMonitoringIp(dstIp);
ipPacketCache.asMap().compute(dstIp, (ip, queue) -> {
if (queue == null) {
queue = new ConcurrentLinkedQueue<>();
}
queue.add((IP) eth.getPayload());
return queue;
});
}
return true;
}
use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class MplsTest method testIpv4OverMplsDeserialize.
@Test
public void testIpv4OverMplsDeserialize() throws Exception {
// Serialize
byte[] packet = ETH_IPV4.serialize();
assertThat(MPLS_IPV4.protocol, is(PROTOCOL_MPLS));
assertThat(MPLS_IPV4.bos, is((byte) 0));
assertThat(MPLS_BOS_IPV4.protocol, is(PROTOCOL_IPV4));
assertThat(MPLS_BOS_IPV4.bos, is((byte) 1));
// Deserialize
Ethernet ethernet;
ethernet = Ethernet.deserializer().deserialize(packet, 0, packet.length);
// Verify
assertNotNull(ethernet);
assertThat(ethernet.getSourceMAC(), is(ETH_IPV4.getSourceMAC()));
assertThat(ethernet.getDestinationMAC(), is(ETH_IPV4.getDestinationMAC()));
assertThat(ethernet.getEtherType(), is(Ethernet.MPLS_UNICAST));
assertTrue(ethernet.getPayload() instanceof MPLS);
MPLS mpls = (MPLS) ethernet.getPayload();
assertThat(mpls.getLabel(), is(1));
assertThat(mpls.getTtl(), is((byte) 0));
assertThat(mpls.protocol, is(PROTOCOL_MPLS));
assertThat(mpls.bos, is((byte) 0));
assertTrue(mpls.getPayload() instanceof MPLS);
mpls = (MPLS) mpls.getPayload();
assertThat(mpls.getLabel(), is(101));
assertThat(mpls.getTtl(), is((byte) 0));
assertThat(mpls.protocol, is(PROTOCOL_IPV4));
assertThat(mpls.bos, is((byte) 1));
IPv4 ip = (IPv4) mpls.getPayload();
assertThat(ip.getSourceAddress(), is(SRC_IPV4.toInt()));
assertThat(ip.getDestinationAddress(), is(DST_IPV4.toInt()));
assertTrue(ip.getPayload() instanceof ICMP);
ICMP icmp = (ICMP) ip.getPayload();
assertThat(icmp.getIcmpType(), is(TYPE_ECHO_REQUEST));
}
use of org.onlab.packet.IPv4 in project onos by opennetworkinglab.
the class PimInterface method processHello.
/**
* Process an incoming PIM Hello message. There are a few things going on in
* this method:
* <ul>
* <li>We <em>may</em> have to create a new neighbor if one does not already exist</li>
* <li>We <em>may</em> need to re-elect a new DR if new information is received</li>
* <li>We <em>may</em> need to send an existing neighbor all joins if the genid changed</li>
* <li>We will refresh the neighbor's timestamp</li>
* </ul>
*
* @param ethPkt the Ethernet packet header
*/
public void processHello(Ethernet ethPkt) {
if (log.isTraceEnabled()) {
log.trace("Received a PIM hello packet");
}
// We'll need to save our neighbors MAC address
MacAddress nbrmac = ethPkt.getSourceMAC();
// And we'll need to save neighbors IP Address.
IPv4 iphdr = (IPv4) ethPkt.getPayload();
IpAddress srcip = IpAddress.valueOf(iphdr.getSourceAddress());
PIM pimhdr = (PIM) iphdr.getPayload();
if (pimhdr.getPimMsgType() != PIM.TYPE_HELLO) {
log.error("process Hello has received a non hello packet type: " + pimhdr.getPimMsgType());
return;
}
// get the DR values for later calculation
PimNeighbor dr = pimNeighbors.get(drIpaddress);
checkNotNull(dr);
IpAddress drip = drIpaddress;
int drpri = dr.priority();
// Assume we do not need to run a DR election
boolean reElectDr = false;
boolean genidChanged = false;
PIMHello hello = (PIMHello) pimhdr.getPayload();
// Determine if we already have a PIMNeighbor
PimNeighbor nbr = pimNeighbors.getOrDefault(srcip, null);
PimNeighbor newNbr = PimNeighbor.createPimNeighbor(srcip, nbrmac, hello.getOptions().values());
if (nbr == null) {
pimNeighbors.putIfAbsent(srcip, newNbr);
nbr = newNbr;
} else if (!nbr.equals(newNbr)) {
if (newNbr.holdtime() == 0) {
// Neighbor has shut down. Remove them and clean up
pimNeighbors.remove(srcip, nbr);
return;
} else {
// Neighbor has changed one of their options.
pimNeighbors.put(srcip, newNbr);
nbr = newNbr;
}
}
// Refresh this neighbor's timestamp
nbr.refreshTimestamp();
/*
* the election method will first determine if an election
* needs to be run, if so it will run the election. The
* IP address of the DR will be returned. If the IP address
* of the DR is different from what we already have we know a
* new DR has been elected.
*/
IpAddress electedIp = election(nbr, drip, drpri);
if (!drip.equals(electedIp)) {
// we have a new DR.
drIpaddress = electedIp;
}
}
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);
}
Aggregations