use of org.onosproject.net.intf.Interface 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.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class Dhcp4HandlerImpl method processDhcpPacket.
@Override
public void processDhcpPacket(PacketContext context, BasePacket payload) {
checkNotNull(payload, "DHCP payload can't be null");
checkState(payload instanceof DHCP, "Payload is not a DHCP");
DHCP dhcpPayload = (DHCP) payload;
if (!configured()) {
log.warn("Missing default DHCP relay server config. Abort packet processing");
return;
}
ConnectPoint inPort = context.inPacket().receivedFrom();
checkNotNull(dhcpPayload, "Can't find DHCP payload");
Ethernet packet = context.inPacket().parsed();
DHCP.MsgType incomingPacketType = dhcpPayload.getOptions().stream().filter(dhcpOption -> dhcpOption.getCode() == OptionCode_MessageType.getValue()).map(DhcpOption::getData).map(data -> DHCP.MsgType.getType(data[0])).findFirst().orElse(null);
checkNotNull(incomingPacketType, "Can't get message type from DHCP payload {}", dhcpPayload);
Set<Interface> receivingInterfaces = interfaceService.getInterfacesByPort(inPort);
// ignore the packets if dhcp client interface is not configured on onos.
if (receivingInterfaces.isEmpty()) {
log.warn("Virtual interface is not configured on {}", inPort);
return;
}
switch(incomingPacketType) {
case DHCPDISCOVER:
// Add the gateway IP as virtual interface IP for server to understand
// the lease to be assigned and forward the packet to dhcp server.
List<InternalPacket> ethernetClientPacket = processDhcpPacketFromClient(context, packet, receivingInterfaces);
for (InternalPacket internalPacket : ethernetClientPacket) {
log.debug("DHCPDISCOVER from {} Forward to server", inPort);
writeRequestDhcpRecord(inPort, packet, dhcpPayload);
forwardPacket(internalPacket);
}
break;
case DHCPOFFER:
// reply to dhcp client.
InternalPacket ethernetPacketOffer = processDhcpPacketFromServer(context, packet);
if (ethernetPacketOffer != null) {
writeResponseDhcpRecord(ethernetPacketOffer.getPacket(), dhcpPayload);
sendResponseToClient(ethernetPacketOffer, dhcpPayload);
}
break;
case DHCPREQUEST:
// add the gateway ip as virtual interface ip for server to understand
// the lease to be assigned and forward the packet to dhcp server.
List<InternalPacket> ethernetPacketRequest = processDhcpPacketFromClient(context, packet, receivingInterfaces);
for (InternalPacket internalPacket : ethernetPacketRequest) {
log.debug("DHCPDISCOVER from {} Forward to server", inPort);
writeRequestDhcpRecord(inPort, packet, dhcpPayload);
forwardPacket(internalPacket);
}
break;
case DHCPDECLINE:
break;
case DHCPACK:
// reply to dhcp client.
InternalPacket ethernetPacketAck = processDhcpPacketFromServer(context, packet);
if (ethernetPacketAck != null) {
writeResponseDhcpRecord(ethernetPacketAck.getPacket(), dhcpPayload);
handleDhcpAck(ethernetPacketAck.getPacket(), dhcpPayload);
sendResponseToClient(ethernetPacketAck, dhcpPayload);
}
break;
case DHCPNAK:
break;
case DHCPRELEASE:
// TODO: release the ip address from client
break;
case DHCPINFORM:
break;
case DHCPFORCERENEW:
break;
case DHCPLEASEQUERY:
handleLeaseQueryMsg(context, packet, dhcpPayload);
break;
case DHCPLEASEACTIVE:
handleLeaseQueryActivateMsg(packet, dhcpPayload);
break;
case DHCPLEASEUNASSIGNED:
case DHCPLEASEUNKNOWN:
handleLeaseQueryUnknown(packet, dhcpPayload);
break;
default:
break;
}
}
use of org.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class Dhcp6HandlerImpl 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 -> Dhcp6HandlerUtil.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 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.onosproject.net.intf.Interface in project onos by opennetworkinglab.
the class SimpleFabricForwarding method buildBrcIntents.
// Build Boadcast Intents for a L2 Network.
private Set<SinglePointToMultiPointIntent> buildBrcIntents(FabricNetwork fabricNetwork) {
Set<Interface> interfaces = fabricNetwork.interfaces();
if (interfaces.size() < 2 || !fabricNetwork.isForward() || !fabricNetwork.isBroadcast()) {
return ImmutableSet.of();
}
Set<SinglePointToMultiPointIntent> brcIntents = Sets.newHashSet();
ResourceGroup resourceGroup = ResourceGroup.of(fabricNetwork.name());
// Generates broadcast Intents from any network interface to other
// network interface from the L2 Network.
interfaces.forEach(src -> {
FilteredConnectPoint srcFcp = buildFilteredConnectedPoint(src);
Set<FilteredConnectPoint> dstFcps = interfaces.stream().filter(iface -> !iface.equals(src)).map(this::buildFilteredConnectedPoint).collect(Collectors.toSet());
Key key = buildKey(fabricNetwork.name(), "BCAST", srcFcp.connectPoint(), MacAddress.BROADCAST);
TrafficSelector selector = DefaultTrafficSelector.builder().matchEthDst(MacAddress.BROADCAST).build();
SinglePointToMultiPointIntent.Builder intentBuilder = SinglePointToMultiPointIntent.builder().appId(appId).key(key).selector(selector).filteredIngressPoint(srcFcp).filteredEgressPoints(dstFcps).constraints(buildConstraints(L2NETWORK_CONSTRAINTS, fabricNetwork.encapsulation())).priority(PRI_L2NETWORK_BROADCAST).resourceGroup(resourceGroup);
brcIntents.add(intentBuilder.build());
});
return brcIntents;
}
Aggregations