use of org.onlab.packet.ARP in project onos by opennetworkinglab.
the class OpenFlowPacketProviderTest method emit.
@Test
public void emit() {
MacAddress mac1 = MacAddress.of("00:00:00:11:00:01");
MacAddress mac2 = MacAddress.of("00:00:00:22:00:02");
ARP arp = new ARP();
arp.setSenderProtocolAddress(ANY).setSenderHardwareAddress(mac1.getBytes()).setTargetHardwareAddress(mac2.getBytes()).setTargetProtocolAddress(ANY).setHardwareType((short) 0).setProtocolType((short) 0).setHardwareAddressLength((byte) 6).setProtocolAddressLength((byte) 4).setOpCode((byte) 0);
Ethernet eth = new Ethernet();
eth.setVlanID(VLANID).setEtherType(Ethernet.TYPE_ARP).setSourceMACAddress("00:00:00:11:00:01").setDestinationMACAddress("00:00:00:22:00:02").setPayload(arp);
// the should-be working setup.
OutboundPacket passPkt = outPacket(DID, TR, eth);
sw.setRole(RoleState.MASTER);
provider.emit(passPkt);
assertEquals("invalid switch", sw, controller.current);
assertEquals("message not sent", PLIST.size(), sw.sent.size());
sw.sent.clear();
// Send with different IN_PORT
OutboundPacket inPortPkt = outPacket(DID, TR_ALL, eth, IN_PORT);
sw.setRole(RoleState.MASTER);
provider.emit(inPortPkt);
assertEquals("invalid switch", sw, controller.current);
assertEquals("message not sent", PLIST_ALL.size(), sw.sent.size());
OFMessage ofMessage = sw.sent.get(0);
assertEquals("Wrong OF message type", OFType.PACKET_OUT, ofMessage.getType());
OFPacketOut packetOut = (OFPacketOut) ofMessage;
assertEquals("Wrong in port", OFPort.of(IN_PORT_PN), packetOut.getInPort());
assertEquals("Unexpected number of actions", 1, packetOut.getActions().size());
OFAction ofAction = packetOut.getActions().get(0);
assertEquals("Packet out action should be type output", OFActionType.OUTPUT, ofAction.getType());
OFActionOutput ofActionOutput = (OFActionOutput) ofAction;
assertEquals("Output should be ALL", OFPort.ALL, ofActionOutput.getPort());
sw.sent.clear();
// wrong Role
// sw.setRole(RoleState.SLAVE);
// provider.emit(passPkt);
// assertEquals("invalid switch", sw, controller.current);
// assertEquals("message sent incorrectly", 0, sw.sent.size());
// sw.setRole(RoleState.MASTER);
// missing switch
OutboundPacket swFailPkt = outPacket(DID_MISSING, TR, eth);
provider.emit(swFailPkt);
assertNull("invalid switch", controller.current);
assertEquals("message sent incorrectly", 0, sw.sent.size());
// to missing port
// OutboundPacket portFailPkt = outPacket(DID, TR_MISSING, eth);
// provider.emit(portFailPkt);
// assertEquals("extra message sent", 1, sw.sent.size());
}
use of org.onlab.packet.ARP in project onos by opennetworkinglab.
the class K8sSwitchingArpHandler method processArpReply.
private void processArpReply(PacketContext context, Ethernet ethPacket) {
ARP arpPacket = (ARP) ethPacket.getPayload();
IpAddress srcIp = IpAddress.valueOf(INET, arpPacket.getSenderProtocolAddress());
MacAddress srcMac = MacAddress.valueOf(arpPacket.getSenderHardwareAddress());
IpAddress dstIp = IpAddress.valueOf(INET, arpPacket.getTargetProtocolAddress());
if (dstIp.equals(IpAddress.valueOf(NODE_FAKE_IP_STR))) {
// mutable MAP scenario is not considered for now
if (!extHostMacStore.containsKey(srcIp)) {
extHostMacStore.put(srcIp, srcMac);
}
K8sNode k8sNode = k8sNodeService.nodes().stream().filter(n -> n.nodeIp().equals(srcIp)).findAny().orElse(null);
if (k8sNode == null) {
return;
} else {
if (k8sNode.nodeInfo().nodeMac() != null) {
return;
}
}
// we update node MAC address which will be referred in node port scenario
K8sNodeInfo nodeInfo = new K8sNodeInfo(k8sNode.nodeIp(), srcMac);
K8sNode updatedNode = k8sNode.updateNodeInfo(nodeInfo);
k8sNodeService.updateNode(updatedNode);
}
}
use of org.onlab.packet.ARP in project onos by opennetworkinglab.
the class NeighbourTestUtils method createArpRequest.
/**
* Creates an ARP request for the given target IP.
*
* @param targetIp IP address
* @return ARP request packet
*/
public static Ethernet createArpRequest(IpAddress targetIp) {
Ethernet eth = new Ethernet();
eth.setDestinationMACAddress(MAC1);
eth.setSourceMACAddress(MAC2);
eth.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(MAC2.toBytes());
arp.setTargetHardwareAddress(MacAddress.ZERO.toBytes());
arp.setTargetProtocolAddress(targetIp.toOctets());
arp.setSenderProtocolAddress(IP2.toOctets());
eth.setPayload(arp);
return eth;
}
use of org.onlab.packet.ARP in project onos by opennetworkinglab.
the class OpenstackRoutingArpHandler method processArpPacket.
private void processArpPacket(PacketContext context, Ethernet ethernet) {
ARP arp = (ARP) ethernet.getPayload();
if (arp.getOpCode() == ARP.OP_REQUEST && ARP_PROXY_MODE.equals(getArpMode())) {
if (log.isTraceEnabled()) {
log.trace("ARP request received from {} for {}", Ip4Address.valueOf(arp.getSenderProtocolAddress()).toString(), Ip4Address.valueOf(arp.getTargetProtocolAddress()).toString());
}
IpAddress targetIp = Ip4Address.valueOf(arp.getTargetProtocolAddress());
MacAddress targetMac = null;
NetFloatingIP floatingIP = osRouterAdminService.floatingIps().stream().filter(ip -> ip.getFloatingIpAddress().equals(targetIp.toString())).findAny().orElse(null);
// In case target ip is for associated floating ip, sets target mac to vm's.
if (floatingIP != null && floatingIP.getPortId() != null) {
InstancePort instPort = instancePortService.instancePort(floatingIP.getPortId());
if (instPort == null) {
log.trace("Unknown target ARP request for {}, ignore it", targetIp);
return;
} else {
targetMac = instPort.macAddress();
}
OpenstackNode gw = getGwByInstancePort(osNodeService.completeNodes(GATEWAY), instPort);
if (gw == null) {
return;
}
// if the ARP packet_in received from non-relevant GWs, we simply ignore it
if (!Objects.equals(gw.intgBridge(), context.inPacket().receivedFrom().deviceId())) {
return;
}
}
if (isExternalGatewaySourceIp(targetIp)) {
targetMac = Constants.DEFAULT_GATEWAY_MAC;
}
if (targetMac == null) {
log.trace("Unknown target ARP request for {}, ignore it", targetIp);
return;
}
Ethernet ethReply = ARP.buildArpReply(targetIp.getIp4Address(), targetMac, ethernet);
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();
}
if (arp.getOpCode() == ARP.OP_REPLY) {
ConnectPoint cp = context.inPacket().receivedFrom();
PortNumber receivedPortNum = cp.port();
IpAddress spa = Ip4Address.valueOf(arp.getSenderProtocolAddress());
MacAddress sha = MacAddress.valueOf(arp.getSenderHardwareAddress());
log.debug("ARP reply ip: {}, mac: {}", spa, sha);
try {
Set<String> extRouterIps = osNetworkService.externalPeerRouters().stream().map(r -> r.ipAddress().toString()).collect(Collectors.toSet());
// if SPA is NOT contained in existing external router IP set, we ignore it
if (!extRouterIps.contains(spa.toString())) {
return;
}
OpenstackNode node = osNodeService.node(cp.deviceId());
if (node == null) {
return;
}
// we only handles the ARP-Reply message received by gateway node
if (node.type() != GATEWAY) {
return;
}
if (receivedPortNum.equals(node.uplinkPortNum())) {
osNetworkAdminService.updateExternalPeerRouterMac(spa, sha);
}
} catch (Exception e) {
log.error("Exception occurred because of {}", e);
}
}
}
use of org.onlab.packet.ARP in project onos by opennetworkinglab.
the class OpenstackSwitchingArpHandler method processPacketIn.
/**
* Processes ARP request packets.
* It checks if the target IP is owned by a known host first and then ask to
* OpenStack if it's not. This ARP proxy does not support overlapping IP.
*
* @param context packet context
* @param ethPacket ethernet packet
*/
private void processPacketIn(PacketContext context, Ethernet ethPacket) {
// if the ARP mode is configured as broadcast mode, we simply ignore ARP packet_in
if (ARP_BROADCAST_MODE.equals(getArpMode())) {
return;
}
ARP arpPacket = (ARP) ethPacket.getPayload();
if (arpPacket.getOpCode() != ARP.OP_REQUEST) {
return;
}
InstancePort srcInstPort = instancePortService.instancePort(ethPacket.getSourceMAC());
if (srcInstPort == null) {
log.trace("Failed to find source instance port(MAC:{})", ethPacket.getSourceMAC());
return;
}
IpAddress targetIp = Ip4Address.valueOf(arpPacket.getTargetProtocolAddress());
MacAddress replyMac = isGatewayIp(targetIp) ? MacAddress.valueOf(gatewayMac) : getMacFromHostOpenstack(targetIp, srcInstPort.networkId());
if (replyMac == MacAddress.NONE) {
log.trace("Failed to find MAC address for {}", targetIp);
return;
}
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())));
}
Aggregations