use of org.onlab.packet.Ethernet in project onos by opennetworkinglab.
the class K8sRoutingArpHandler method processArpPacket.
private void processArpPacket(PacketContext context, Ethernet ethernet) {
DeviceId deviceId = context.inPacket().receivedFrom().deviceId();
if (!allK8sDevices(k8sNodeService, k8sHostService).contains(deviceId)) {
return;
}
ARP arp = (ARP) ethernet.getPayload();
if (arp.getOpCode() == ARP.OP_REPLY) {
IpAddress spa = Ip4Address.valueOf(arp.getSenderProtocolAddress());
MacAddress sha = MacAddress.valueOf(arp.getSenderHardwareAddress());
log.info("ARP reply from ip: {}, mac: {}", spa, sha);
Set<IpAddress> gatewayIps = k8sNodeService.completeNodes().stream().map(K8sNode::extGatewayIp).collect(Collectors.toSet());
if (!gatewayIps.contains(spa)) {
return;
}
log.info("ARP reply from external gateway ip: {}, mac: {}", spa, sha);
k8sNodeService.completeNodes().stream().filter(n -> n.extGatewayMac() == null).forEach(n -> {
K8sNode updated = n.updateExtGatewayMac(sha);
k8sNodeService.updateNode(updated);
});
}
}
use of org.onlab.packet.Ethernet in project onos by opennetworkinglab.
the class K8sSwitchingArpHandler method processArpRequest.
private void processArpRequest(PacketContext context, Ethernet ethPacket) {
ARP arpPacket = (ARP) ethPacket.getPayload();
K8sPort srcK8sPort = k8sNetworkService.ports().stream().filter(p -> p.macAddress().equals(ethPacket.getSourceMAC())).findAny().orElse(null);
PortNumber srcPortNum = context.inPacket().receivedFrom().port();
DeviceId srcDeviceId = context.inPacket().receivedFrom().deviceId();
boolean isEntryPort = false;
for (K8sNode node : k8sNodeService.completeNodes()) {
if (srcDeviceId.equals(node.intgBridge()) && srcPortNum.equals(node.intgEntryPortNum())) {
isEntryPort = true;
}
}
// integration bridge entry port, we simply ignore the ARP request...
if (srcK8sPort == null && !isEntryPort) {
log.warn("Failed to find source port(MAC:{})", ethPacket.getSourceMAC());
return;
}
IpAddress targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
// look up the MAC address from regular k8s ports
MacAddress replyMac = k8sNetworkService.ports().stream().filter(p -> p.ipAddress().equals(targetIp)).map(K8sPort::macAddress).findAny().orElse(null);
// look up the MAC address from special integration entry port (e.g., LOCAL, k8s-int-os)
for (K8sNetwork network : k8sNetworkService.networks()) {
if (network.gatewayIp().equals(targetIp)) {
K8sNode node = k8sNodeService.node(network.name());
replyMac = node.intgEntryPortMac();
}
}
if (replyMac == null) {
String cidr = k8sNetworkService.networks().stream().map(K8sNetwork::cidr).findAny().orElse(null);
if (cidr != null) {
String unshiftedIp = unshiftIpDomain(targetIp.toString(), SHIFTED_IP_PREFIX, cidr);
replyMac = k8sNetworkService.ports().stream().filter(p -> p.ipAddress().equals(IpAddress.valueOf(unshiftedIp))).map(K8sPort::macAddress).findAny().orElse(null);
}
}
if (replyMac == null) {
Set<String> serviceIps = k8sServiceService.services().stream().map(s -> s.getSpec().getClusterIP()).collect(Collectors.toSet());
if (serviceIps.contains(targetIp.toString())) {
replyMac = MacAddress.valueOf(SERVICE_FAKE_MAC_STR);
}
}
if (replyMac == null) {
if (targetIp.toString().startsWith(NODE_IP_PREFIX)) {
String targetIpPrefix = targetIp.toString().split("\\.")[1];
String nodePrefix = NODE_IP_PREFIX + "." + targetIpPrefix;
String origNodeCidr = k8sNodeService.completeNodes().stream().map(n -> n.nodeIp().toString()).findAny().orElse(null);
if (origNodeCidr != null) {
String origNodeIp = unshiftIpDomain(targetIp.toString(), nodePrefix, origNodeCidr);
IpPrefix k8sNodeIpCidr = IpPrefix.valueOf(IpAddress.valueOf(origNodeCidr), 24);
SubnetUtils k8sNodeSubnet = new SubnetUtils(k8sNodeIpCidr.toString());
String k8sNodeGateway = getGatewayIp(k8sNodeIpCidr.toString()).toString();
String seekIp = "";
if (!k8sNodeSubnet.getInfo().isInRange(origNodeIp)) {
replyMac = extHostMacStore.asJavaMap().get(IpAddress.valueOf(k8sNodeGateway));
seekIp = k8sNodeGateway;
} else {
replyMac = extHostMacStore.asJavaMap().get(IpAddress.valueOf(origNodeIp));
seekIp = origNodeIp;
}
// we need to manually learn their MAC addresses
if (replyMac == null) {
ConnectPoint cp = context.inPacket().receivedFrom();
K8sNode k8sNode = k8sNodeService.node(cp.deviceId());
if (k8sNode != null) {
// we use fake IP and MAC address as a source to
// query destination MAC address
setArpRequest(MacAddress.valueOf(NODE_FAKE_MAC_STR).toBytes(), IpAddress.valueOf(NODE_FAKE_IP_STR).toOctets(), IpAddress.valueOf(seekIp).toOctets(), k8sNode);
context.block();
return;
}
}
}
}
}
if (replyMac == null) {
replyMac = MacAddress.valueOf(gatewayMac);
}
Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(), replyMac, ethPacket);
TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(context.inPacket().receivedFrom().port()).build();
packetService.emit(new DefaultOutboundPacket(context.inPacket().receivedFrom().deviceId(), treatment, ByteBuffer.wrap(ethReply.serialize())));
context.block();
}
use of org.onlab.packet.Ethernet in project onos by opennetworkinglab.
the class KubevirtFloatingIpHandler method processGarpPacketForFloatingIp.
private void processGarpPacketForFloatingIp(KubevirtFloatingIp floatingIp, KubevirtNode electedGw) {
if (floatingIp == null) {
return;
}
KubevirtPort kubevirtPort = getKubevirtPortByFloatingIp(floatingIp);
if (kubevirtPort == null) {
return;
}
Ethernet ethernet = buildGarpPacket(kubevirtPort.macAddress(), floatingIp.floatingIp());
if (ethernet == null) {
return;
}
TrafficTreatment treatment = DefaultTrafficTreatment.builder().setOutput(externalPatchPortNum(deviceService, electedGw)).build();
packetService.emit(new DefaultOutboundPacket(electedGw.intgBridge(), treatment, ByteBuffer.wrap(ethernet.serialize())));
}
use of org.onlab.packet.Ethernet in project onos by opennetworkinglab.
the class KubevirtNetworkingUtil method buildGarpPacket.
/**
* Builds a GARP packet using the given source MAC and source IP address.
*
* @param srcMac source MAC address
* @param srcIp source IP address
* @return GARP packet
*/
public static Ethernet buildGarpPacket(MacAddress srcMac, IpAddress srcIp) {
if (srcMac == null || srcIp == null) {
return null;
}
Ethernet ethernet = new Ethernet();
ethernet.setDestinationMACAddress(MacAddress.BROADCAST);
ethernet.setSourceMACAddress(srcMac);
ethernet.setEtherType(Ethernet.TYPE_ARP);
ARP arp = new ARP();
arp.setOpCode(ARP.OP_REPLY);
arp.setProtocolType(ARP.PROTO_TYPE_IP);
arp.setHardwareType(ARP.HW_TYPE_ETHERNET);
arp.setProtocolAddressLength((byte) Ip4Address.BYTE_LENGTH);
arp.setHardwareAddressLength((byte) Ethernet.DATALAYER_ADDRESS_LENGTH);
arp.setSenderHardwareAddress(srcMac.toBytes());
arp.setTargetHardwareAddress(MacAddress.BROADCAST.toBytes());
arp.setSenderProtocolAddress(srcIp.toOctets());
arp.setTargetProtocolAddress(srcIp.toOctets());
ethernet.setPayload(arp);
return ethernet;
}
use of org.onlab.packet.Ethernet 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;
}
Aggregations