use of org.onlab.packet.ICMP6 in project onos by opennetworkinglab.
the class ReactiveForwarding method installRule.
// Install a rule forwarding the packet to the specified port.
private void installRule(PacketContext context, PortNumber portNumber, ReactiveForwardMetrics macMetrics) {
//
// We don't support (yet) buffer IDs in the Flow Service so
// packet out first.
//
Ethernet inPkt = context.inPacket().parsed();
TrafficSelector.Builder selectorBuilder = DefaultTrafficSelector.builder();
// If PacketOutOnly or ARP packet than forward directly to output port
if (packetOutOnly || inPkt.getEtherType() == Ethernet.TYPE_ARP) {
packetOut(context, portNumber, macMetrics);
return;
}
//
if (matchDstMacOnly) {
selectorBuilder.matchEthDst(inPkt.getDestinationMAC());
} else {
selectorBuilder.matchInPort(context.inPacket().receivedFrom().port()).matchEthSrc(inPkt.getSourceMAC()).matchEthDst(inPkt.getDestinationMAC());
// If configured Match Vlan ID
if (matchVlanId && inPkt.getVlanID() != Ethernet.VLAN_UNTAGGED) {
selectorBuilder.matchVlanId(VlanId.vlanId(inPkt.getVlanID()));
}
//
if (matchIpv4Address && inPkt.getEtherType() == Ethernet.TYPE_IPV4) {
IPv4 ipv4Packet = (IPv4) inPkt.getPayload();
byte ipv4Protocol = ipv4Packet.getProtocol();
Ip4Prefix matchIp4SrcPrefix = Ip4Prefix.valueOf(ipv4Packet.getSourceAddress(), Ip4Prefix.MAX_MASK_LENGTH);
Ip4Prefix matchIp4DstPrefix = Ip4Prefix.valueOf(ipv4Packet.getDestinationAddress(), Ip4Prefix.MAX_MASK_LENGTH);
selectorBuilder.matchEthType(Ethernet.TYPE_IPV4).matchIPSrc(matchIp4SrcPrefix).matchIPDst(matchIp4DstPrefix);
if (matchIpv4Dscp) {
byte dscp = ipv4Packet.getDscp();
byte ecn = ipv4Packet.getEcn();
selectorBuilder.matchIPDscp(dscp).matchIPEcn(ecn);
}
if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_TCP) {
TCP tcpPacket = (TCP) ipv4Packet.getPayload();
selectorBuilder.matchIPProtocol(ipv4Protocol).matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort())).matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort()));
}
if (matchTcpUdpPorts && ipv4Protocol == IPv4.PROTOCOL_UDP) {
UDP udpPacket = (UDP) ipv4Packet.getPayload();
selectorBuilder.matchIPProtocol(ipv4Protocol).matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort())).matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));
}
if (matchIcmpFields && ipv4Protocol == IPv4.PROTOCOL_ICMP) {
ICMP icmpPacket = (ICMP) ipv4Packet.getPayload();
selectorBuilder.matchIPProtocol(ipv4Protocol).matchIcmpType(icmpPacket.getIcmpType()).matchIcmpCode(icmpPacket.getIcmpCode());
}
}
//
if (matchIpv6Address && inPkt.getEtherType() == Ethernet.TYPE_IPV6) {
IPv6 ipv6Packet = (IPv6) inPkt.getPayload();
byte ipv6NextHeader = ipv6Packet.getNextHeader();
Ip6Prefix matchIp6SrcPrefix = Ip6Prefix.valueOf(ipv6Packet.getSourceAddress(), Ip6Prefix.MAX_MASK_LENGTH);
Ip6Prefix matchIp6DstPrefix = Ip6Prefix.valueOf(ipv6Packet.getDestinationAddress(), Ip6Prefix.MAX_MASK_LENGTH);
selectorBuilder.matchEthType(Ethernet.TYPE_IPV6).matchIPv6Src(matchIp6SrcPrefix).matchIPv6Dst(matchIp6DstPrefix);
if (matchIpv6FlowLabel) {
selectorBuilder.matchIPv6FlowLabel(ipv6Packet.getFlowLabel());
}
if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_TCP) {
TCP tcpPacket = (TCP) ipv6Packet.getPayload();
selectorBuilder.matchIPProtocol(ipv6NextHeader).matchTcpSrc(TpPort.tpPort(tcpPacket.getSourcePort())).matchTcpDst(TpPort.tpPort(tcpPacket.getDestinationPort()));
}
if (matchTcpUdpPorts && ipv6NextHeader == IPv6.PROTOCOL_UDP) {
UDP udpPacket = (UDP) ipv6Packet.getPayload();
selectorBuilder.matchIPProtocol(ipv6NextHeader).matchUdpSrc(TpPort.tpPort(udpPacket.getSourcePort())).matchUdpDst(TpPort.tpPort(udpPacket.getDestinationPort()));
}
if (matchIcmpFields && ipv6NextHeader == IPv6.PROTOCOL_ICMP6) {
ICMP6 icmp6Packet = (ICMP6) ipv6Packet.getPayload();
selectorBuilder.matchIPProtocol(ipv6NextHeader).matchIcmpv6Type(icmp6Packet.getIcmpType()).matchIcmpv6Code(icmp6Packet.getIcmpCode());
}
}
}
TrafficTreatment treatment;
if (inheritFlowTreatment) {
treatment = context.treatmentBuilder().setOutput(portNumber).build();
} else {
treatment = DefaultTrafficTreatment.builder().setOutput(portNumber).build();
}
ForwardingObjective forwardingObjective = DefaultForwardingObjective.builder().withSelector(selectorBuilder.build()).withTreatment(treatment).withPriority(flowPriority).withFlag(ForwardingObjective.Flag.VERSATILE).fromApp(appId).makeTemporary(flowTimeout).add();
flowObjectiveService.forward(context.inPacket().receivedFrom().deviceId(), forwardingObjective);
forwardPacket(macMetrics);
//
if (packetOutOfppTable) {
packetOut(context, PortNumber.TABLE, macMetrics);
} else {
packetOut(context, portNumber, macMetrics);
}
}
use of org.onlab.packet.ICMP6 in project onos by opennetworkinglab.
the class DefaultNeighbourMessageActions method buildNdpReply.
/**
* Builds an NDP reply based on a request.
*
* @param srcIp the IP address to use as the reply source
* @param srcMac the MAC address to use as the reply source
* @param request the Neighbor Solicitation request we got
* @param isRouter true if this reply is sent on behalf of a router
* @return an Ethernet frame containing the Neighbor Advertisement reply
*/
private Ethernet buildNdpReply(Ip6Address srcIp, MacAddress srcMac, Ethernet request, boolean isRouter) {
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(request.getSourceMAC());
eth.setSourceMACAddress(srcMac);
eth.setEtherType(Ethernet.TYPE_IPV6);
eth.setVlanID(request.getVlanID());
IPv6 requestIp = (IPv6) request.getPayload();
IPv6 ipv6 = new IPv6();
ipv6.setSourceAddress(srcIp.toOctets());
ipv6.setDestinationAddress(requestIp.getSourceAddress());
ipv6.setHopLimit((byte) 255);
ICMP6 icmp6 = new ICMP6();
icmp6.setIcmpType(ICMP6.NEIGHBOR_ADVERTISEMENT);
icmp6.setIcmpCode((byte) 0);
NeighborAdvertisement nadv = new NeighborAdvertisement();
nadv.setTargetAddress(srcIp.toOctets());
nadv.setSolicitedFlag((byte) 1);
nadv.setOverrideFlag((byte) 1);
if (isRouter) {
nadv.setRouterFlag((byte) 1);
}
nadv.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS, srcMac.toBytes());
icmp6.setPayload(nadv);
ipv6.setPayload(icmp6);
eth.setPayload(ipv6);
return eth;
}
use of org.onlab.packet.ICMP6 in project onos by opennetworkinglab.
the class DefaultNeighbourMessageContext method createNdpContext.
/**
* Extracts context information from NDP packets.
*
* @param eth input Ethernet frame that is thought to be NDP
* @param inPort in port
* @param actions actions to take
* @return MessageContext object if the packet was a valid NDP packet,
* otherwise null
*/
private static NeighbourMessageContext createNdpContext(Ethernet eth, ConnectPoint inPort, NeighbourMessageActions actions) {
if (eth.getEtherType() != Ethernet.TYPE_IPV6) {
return null;
}
IPv6 ipv6 = (IPv6) eth.getPayload();
if (ipv6.getNextHeader() != IPv6.PROTOCOL_ICMP6) {
return null;
}
ICMP6 icmpv6 = (ICMP6) ipv6.getPayload();
IpAddress sender = Ip6Address.valueOf(ipv6.getSourceAddress());
IpAddress target;
NeighbourMessageType type;
if (icmpv6.getIcmpType() == ICMP6.NEIGHBOR_SOLICITATION) {
type = NeighbourMessageType.REQUEST;
NeighborSolicitation nsol = (NeighborSolicitation) icmpv6.getPayload();
target = Ip6Address.valueOf(nsol.getTargetAddress());
} else if (icmpv6.getIcmpType() == ICMP6.NEIGHBOR_ADVERTISEMENT) {
type = NeighbourMessageType.REPLY;
/*
* sender and target are the same in the reply.
* We use as target the destination ip.
*/
target = Ip6Address.valueOf(ipv6.getDestinationAddress());
} else {
return null;
}
return new DefaultNeighbourMessageContext(actions, eth, inPort, NeighbourProtocol.NDP, type, target, sender);
}
use of org.onlab.packet.ICMP6 in project onos by opennetworkinglab.
the class NeighborAdvertisement method buildNdpAdv.
/**
* Builds an NDP reply based on a request.
*
* @param srcIp the IP address to use as the reply source
* @param srcMac the MAC address to use as the reply source
* @param request the Neighbor Solicitation request we got
* @return an Ethernet frame containing the Neighbor Advertisement reply
*/
public static Ethernet buildNdpAdv(Ip6Address srcIp, MacAddress srcMac, Ethernet request) {
checkNotNull(srcIp, "IP address cannot be null");
checkNotNull(srcMac, "MAC address cannot be null");
checkNotNull(request, "Request cannot be null");
checkArgument(request.getEtherType() == Ethernet.TYPE_IPV6, "EtherType must be IPv6");
final IPv6 ipv6Request = (IPv6) request.getPayload();
checkArgument(ipv6Request.getNextHeader() == IPv6.PROTOCOL_ICMP6, "Protocol must be ICMP6");
final ICMP6 icmpv6 = (ICMP6) ipv6Request.getPayload();
checkArgument(icmpv6.getIcmpType() == ICMP6.NEIGHBOR_SOLICITATION, "ICMP6 type must be NEIGHBOR_SOLICITATION");
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(request.getSourceMAC());
eth.setSourceMACAddress(srcMac);
eth.setEtherType(Ethernet.TYPE_IPV6);
eth.setVlanID(request.getVlanID());
IPv6 ipv6 = new IPv6();
ipv6.setSourceAddress(srcIp.toOctets());
ipv6.setDestinationAddress(ipv6Request.getSourceAddress());
ipv6.setHopLimit(NDP_HOP_LIMIT);
ipv6.setNextHeader(IPv6.PROTOCOL_ICMP6);
ICMP6 icmp6 = new ICMP6();
icmp6.setIcmpType(ICMP6.NEIGHBOR_ADVERTISEMENT);
icmp6.setIcmpCode(RESERVED_CODE);
NeighborAdvertisement nadv = new NeighborAdvertisement();
nadv.setTargetAddress(srcIp.toOctets());
nadv.setSolicitedFlag(NDP_SOLICITED_FLAG);
nadv.setOverrideFlag(NDP_OVERRIDE_FLAG);
nadv.addOption(NeighborDiscoveryOptions.TYPE_TARGET_LL_ADDRESS, srcMac.toBytes());
icmp6.setPayload(nadv);
ipv6.setPayload(icmp6);
eth.setPayload(ipv6);
return eth;
}
use of org.onlab.packet.ICMP6 in project onos by opennetworkinglab.
the class NeighborSolicitation method buildNdpSolicit.
/**
* Builds a NDP solicitation using the supplied parameters.
*
* @param targetIp the target ip
* @param sourceIp the source ip
* @param destinationIp the destination ip
* @param sourceMac the source mac address
* @param destinationMac the destination mac address
* @param vlan the vlan id
* @return the ethernet packet containing the ndp solicitation
*/
public static Ethernet buildNdpSolicit(Ip6Address targetIp, Ip6Address sourceIp, Ip6Address destinationIp, MacAddress sourceMac, MacAddress destinationMac, VlanId vlan) {
checkNotNull(targetIp, "Target IP address cannot be null");
checkNotNull(sourceIp, "Source IP address cannot be null");
checkNotNull(destinationIp, "Destination IP address cannot be null");
checkNotNull(sourceMac, "Source MAC address cannot be null");
checkNotNull(destinationMac, "Destination MAC address cannot be null");
checkNotNull(vlan, "Vlan cannot be null");
// Here we craft the Ethernet packet.
Ethernet ethernet = new Ethernet();
ethernet.setEtherType(Ethernet.TYPE_IPV6).setDestinationMACAddress(destinationMac).setSourceMACAddress(sourceMac);
ethernet.setVlanID(vlan.id());
// IPv6 packet is created.
IPv6 ipv6 = new IPv6();
ipv6.setSourceAddress(sourceIp.toOctets());
ipv6.setDestinationAddress(destinationIp.toOctets());
ipv6.setHopLimit(NDP_HOP_LIMIT);
// Create the ICMPv6 packet.
ICMP6 icmp6 = new ICMP6();
icmp6.setIcmpType(ICMP6.NEIGHBOR_SOLICITATION);
icmp6.setIcmpCode(RESERVED_CODE);
// Create the Neighbor Solicitation packet.
NeighborSolicitation ns = new NeighborSolicitation();
ns.setTargetAddress(targetIp.toOctets());
// DAD packets should not contain SRC_LL_ADDR option
if (!Arrays.equals(sourceIp.toOctets(), Ip6Address.ZERO.toOctets())) {
ns.addOption(NeighborDiscoveryOptions.TYPE_SOURCE_LL_ADDRESS, sourceMac.toBytes());
}
// Set the payloads
icmp6.setPayload(ns);
ipv6.setPayload(icmp6);
ethernet.setPayload(ipv6);
return ethernet;
}
Aggregations