use of org.onlab.packet.IPv6 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.IPv6 in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl method extractPrefix.
/**
* extract from dhcp6 packet Prefix prefix provided by dhcp server.
*
* @param dhcp6 the dhcp6 payload
* @return IpPrefix Prefix Delegation prefix, or null if not exists.
*/
private PdPrefixInfo extractPrefix(DHCP6 dhcp6) {
log.debug("extractPrefix enters {}", dhcp6);
// extract prefix
PdPrefixInfo pdPrefixInfo = new PdPrefixInfo();
Ip6Address prefixAddress = null;
// Extract IPv6 prefix from IA PD option
Optional<Dhcp6IaPdOption> iaPdOption = dhcp6.getOptions().stream().filter(opt -> opt instanceof Dhcp6IaPdOption).map(opt -> (Dhcp6IaPdOption) opt).findFirst();
Optional<Dhcp6IaPrefixOption> iaPrefixOption;
if (iaPdOption.isPresent()) {
log.debug("IA_PD option found {}", iaPdOption);
iaPrefixOption = iaPdOption.get().getOptions().stream().filter(opt -> opt instanceof Dhcp6IaPrefixOption).map(opt -> (Dhcp6IaPrefixOption) opt).findFirst();
} else {
log.debug("IA_PD option NOT found");
iaPrefixOption = Optional.empty();
}
if (iaPrefixOption.isPresent()) {
log.debug("IAPrefix Option within IA_PD option found {}", iaPrefixOption);
prefixAddress = iaPrefixOption.get().getIp6Prefix();
int prefixLen = (int) iaPrefixOption.get().getPrefixLength();
log.debug("Prefix length is {} bits", prefixLen);
pdPrefixInfo.pdPrefix = IpPrefix.valueOf(prefixAddress, prefixLen);
pdPrefixInfo.prefTime = iaPrefixOption.get().getPreferredLifetime();
} else {
log.debug("Can't find IPv6 prefix from DHCPv6 {}", dhcp6);
return null;
}
return pdPrefixInfo;
}
use of org.onlab.packet.IPv6 in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method processLQ6PacketFromServer.
/**
* process the LQ reply packet from dhcp server.
*
* @param defaultServerInfoList default server list
* @param indirectServerInfoList default indirect server list
* @param serverInterface server interface
* @param interfaceService interface service
* @param hostService host service
* @param context packet context
* @param receivedPacket server ethernet packet
* @param recevingInterfaces set of server side interfaces
* @return a packet ready to be sent to relevant output interface
*/
public static InternalPacket processLQ6PacketFromServer(List<DhcpServerInfo> defaultServerInfoList, List<DhcpServerInfo> indirectServerInfoList, Interface serverInterface, InterfaceService interfaceService, HostService hostService, PacketContext context, Ethernet receivedPacket, Set<Interface> recevingInterfaces) {
// get dhcp6 header.
Ethernet etherReply = (Ethernet) receivedPacket.clone();
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
UDP udpPacket = (UDP) ipv6Packet.getPayload();
DHCP6 lq6Reply = (DHCP6) udpPacket.getPayload();
// TODO: refactor
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
DeviceId receivedFromDevice = receivedFrom.deviceId();
DhcpServerInfo serverInfo;
Ip6Address dhcpServerIp = null;
ConnectPoint dhcpServerConnectPoint = null;
MacAddress dhcpConnectMac = null;
VlanId dhcpConnectVlan = null;
Ip6Address dhcpGatewayIp = null;
// todo: refactor
Ip6Address indirectDhcpServerIp = null;
ConnectPoint indirectDhcpServerConnectPoint = null;
MacAddress indirectDhcpConnectMac = null;
VlanId indirectDhcpConnectVlan = null;
Ip6Address indirectDhcpGatewayIp = null;
Ip6Address indirectRelayAgentIpFromCfg = null;
if (!defaultServerInfoList.isEmpty()) {
serverInfo = defaultServerInfoList.get(0);
dhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
dhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
dhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
dhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
dhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
}
if (!indirectServerInfoList.isEmpty()) {
serverInfo = indirectServerInfoList.get(0);
indirectDhcpConnectMac = serverInfo.getDhcpConnectMac().orElse(null);
indirectDhcpGatewayIp = serverInfo.getDhcpGatewayIp6().orElse(null);
indirectDhcpServerIp = serverInfo.getDhcpServerIp6().orElse(null);
indirectDhcpServerConnectPoint = serverInfo.getDhcpServerConnectPoint().orElse(null);
indirectDhcpConnectVlan = serverInfo.getDhcpConnectVlan().orElse(null);
indirectRelayAgentIpFromCfg = serverInfo.getRelayAgentIp6(receivedFromDevice).orElse(null);
}
Boolean directConnFlag = directlyConnected(lq6Reply);
ConnectPoint inPort = context.inPacket().receivedFrom();
if ((directConnFlag || indirectDhcpServerIp == null) && !inPort.equals(dhcpServerConnectPoint)) {
log.warn("Receiving port {} is not the same as server connect point {} for direct or indirect-null", inPort, dhcpServerConnectPoint);
return null;
}
if (!directConnFlag && indirectDhcpServerIp != null && !inPort.equals(indirectDhcpServerConnectPoint)) {
log.warn("Receiving port {} is not the same as server connect point {} for indirect", inPort, indirectDhcpServerConnectPoint);
return null;
}
Ip6Address nextHopIP = Ip6Address.valueOf(ipv6Packet.getDestinationAddress());
// use hosts store to find out the next hop mac and connection point
Set<Host> hosts = hostService.getHostsByIp(nextHopIP);
Host host;
if (!hosts.isEmpty()) {
host = hosts.iterator().next();
} else {
log.warn("Host {} is not in store", nextHopIP);
return null;
}
HostLocation hl = host.location();
// iterator().next());
String clientConnectionPointStr = hl.toString();
ConnectPoint clientConnectionPoint = ConnectPoint.deviceConnectPoint(clientConnectionPointStr);
VlanId originalPacketVlanId = VlanId.vlanId(etherReply.getVlanID());
Interface iface;
iface = interfaceService.getInterfacesByPort(clientConnectionPoint).stream().filter(iface1 -> interfaceContainsVlan(iface1, originalPacketVlanId)).findFirst().orElse(null);
etherReply.setSourceMACAddress(iface.mac());
etherReply.setDestinationMACAddress(host.mac());
// workaround for a bug where core sends src port as 547 (server)
udpPacket.setDestinationPort(UDP.DHCP_V6_SERVER_PORT);
udpPacket.setPayload(lq6Reply);
udpPacket.resetChecksum();
ipv6Packet.setPayload(udpPacket);
etherReply.setPayload(ipv6Packet);
return InternalPacket.internalPacket(etherReply, clientConnectionPoint);
}
use of org.onlab.packet.IPv6 in project onos by opennetworkinglab.
the class Dhcp6HandlerUtil method buildDhcp6PacketFromClient.
/**
* build the DHCP6 solicit/request packet with gatewayip.
*
* @param context packet context
* @param clientPacket client ethernet packet
* @param clientInterfaces set of client side interfaces
* @param serverInfo target server which a packet is generated for
* @param serverInterface target server interface
* @return ethernet packet with dhcp6 packet info
*/
public static Ethernet buildDhcp6PacketFromClient(PacketContext context, Ethernet clientPacket, Set<Interface> clientInterfaces, DhcpServerInfo serverInfo, Interface serverInterface) {
ConnectPoint receivedFrom = context.inPacket().receivedFrom();
DeviceId receivedFromDevice = receivedFrom.deviceId();
Ip6Address relayAgentIp = getRelayAgentIPv6Address(clientInterfaces);
MacAddress relayAgentMac = clientInterfaces.iterator().next().mac();
if (relayAgentIp == null || relayAgentMac == null) {
log.warn("Missing DHCP relay agent interface Ipv6 addr config for " + "packet from client on port: {}. Aborting packet processing", clientInterfaces.iterator().next().connectPoint());
return null;
}
IPv6 clientIpv6 = (IPv6) clientPacket.getPayload();
UDP clientUdp = (UDP) clientIpv6.getPayload();
DHCP6 clientDhcp6 = (DHCP6) clientUdp.getPayload();
boolean directConnFlag = directlyConnected(clientDhcp6);
Ip6Address serverIpFacing = getFirstIpFromInterface(serverInterface);
if (serverIpFacing == null || serverInterface.mac() == null) {
log.warn("No IP v6 address for server Interface {}", serverInterface);
return null;
}
Ethernet etherReply = clientPacket.duplicate();
etherReply.setSourceMACAddress(serverInterface.mac());
// set default info and replace with indirect if available later on.
if (serverInfo.getDhcpConnectMac().isPresent()) {
etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
}
if (serverInfo.getDhcpConnectVlan().isPresent()) {
etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
}
IPv6 ipv6Packet = (IPv6) etherReply.getPayload();
byte[] peerAddress = clientIpv6.getSourceAddress();
ipv6Packet.setSourceAddress(serverIpFacing.toOctets());
ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
UDP udpPacket = (UDP) ipv6Packet.getPayload();
udpPacket.setSourcePort(UDP.DHCP_V6_SERVER_PORT);
DHCP6 dhcp6Packet = (DHCP6) udpPacket.getPayload();
byte[] dhcp6PacketByte = dhcp6Packet.serialize();
DHCP6 dhcp6Relay = new DHCP6();
dhcp6Relay.setMsgType(DHCP6.MsgType.RELAY_FORW.value());
if (directConnFlag) {
dhcp6Relay.setLinkAddress(relayAgentIp.toOctets());
} else {
if (isServerIpEmpty(serverInfo)) {
log.warn("indirect DhcpServerIp empty... use default server ");
} else {
// Check if mac is obtained for valid server ip
if (isConnectMacEmpty(serverInfo, clientInterfaces)) {
log.warn("indirect Dhcp ConnectMac empty ...");
return null;
}
etherReply.setDestinationMACAddress(serverInfo.getDhcpConnectMac().get());
etherReply.setVlanID(serverInfo.getDhcpConnectVlan().get().toShort());
ipv6Packet.setDestinationAddress(serverInfo.getDhcpServerIp6().get().toOctets());
}
if (!serverInfo.getRelayAgentIp6(receivedFromDevice).isPresent()) {
log.debug("indirect connection: relayAgentIp NOT availale from config file! Use dynamic. {}", HexString.toHexString(relayAgentIp.toOctets(), ":"));
serverIpFacing = relayAgentIp;
} else {
serverIpFacing = serverInfo.getRelayAgentIp6(receivedFromDevice).get();
}
log.debug("Source IP address set as relay agent IP with value: {}", serverIpFacing);
dhcp6Relay.setLinkAddress(serverIpFacing.toOctets());
ipv6Packet.setSourceAddress(serverIpFacing.toOctets());
}
// peer address: address of the client or relay agent from which the message to be relayed was received.
dhcp6Relay.setPeerAddress(peerAddress);
// directly connected case, hop count is zero; otherwise, hop count + 1
if (directConnFlag) {
dhcp6Relay.setHopCount((byte) 0);
} else {
dhcp6Relay.setHopCount((byte) (dhcp6Packet.getHopCount() + 1));
}
List<Dhcp6Option> options = new ArrayList<>();
addDhcp6OptionsFromClient(options, dhcp6PacketByte, context, clientPacket);
dhcp6Relay.setOptions(options);
udpPacket.setPayload(dhcp6Relay);
udpPacket.resetChecksum();
ipv6Packet.setPayload(udpPacket);
ipv6Packet.setHopLimit((byte) 64);
etherReply.setPayload(ipv6Packet);
return etherReply;
}
use of org.onlab.packet.IPv6 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);
}
}
Aggregations