Hello,
I created the rules of Packet-IN and Packet-OUT and the package was sent successfully.
Topology:
Flows:
However, when i send a package to the node(10.0.0.2) for another node(10.0.0.4), when i try to redirect it to the node(10.0.0.1), the message reply is denied.
For example:
I've created these flows and initiated the wireshark to monitor the network traffic.
Command:
Flows:
Results of Wireshark- Node(10.0.0.2):
Results of Wireshark- Node(10.0.0.4):
Results of Wireshark- Node(10.0.0.1):
I believe that the message reply for the package is not being created, because the MAC_DST and IP_DST of the package doesn't match with the node that receive the package.
Here is the code:
public class PacketListener implements SequencedPacketListener {
private ProtocolVersion pv = ProtocolVersion.V_1_0;
private short flowTimeout = 800;
private short flowPriority = 3001;
private Set<FlowModFlag> flags = EnumSet.of(FlowModFlag.SEND_FLOW_REM);
@Override
public void errorEvent(ErrorEvent arg0) {
}
@Override
public boolean event(MessageContext context) {
if (context.isHandled())
return false;
MatchFields match = new MatchFields();
ActionFields action = new ActionFields();
Packet decodedPacket = context.decodedPacket();
Ethernet ethernet = decodedPacket.get(ProtocolId.ETHERNET);
Ip ip = decodedPacket.get(ProtocolId.IP);
match.srcIp = ip.srcAddr();
match.srcMac = ethernet.srcAddr();
match.dstIp = ip.dstAddr();
match.dstMac = ethernet.dstAddr();
match.inputPort = context.getPacketIn().getInPort();
action.dataPathId = context.srcEvent().dpid();
if (decodedPacket.has(ProtocolId.TCP)) {
Tcp tcp = decodedPacket.get(ProtocolId.TCP);
match.srcPort = tcp.srcPort();
match.dstPort = tcp.dstPort();
} else if (decodedPacket.has(ProtocolId.UDP)) {
Udp udp = decodedPacket.get(ProtocolId.UDP);
match.srcPort = udp.srcPort();
match.dstPort = udp.dstPort();
} else if (decodedPacket.has(ProtocolId.ICMP)) {
Udp udp = decodedPacket.get(ProtocolId.ICMP);
match.srcPort = udp.srcPort();
match.dstPort = udp.dstPort();
} else {
throw new IllegalArgumentException("packet: Invalid protocol");
}
Action output = ActionFactory.createAction(ProtocolVersion.V_1_0, ActionType.OUTPUT, Port.TABLE);
context.packetOut().addAction(output);
NetworkNode server = doLoadBalancing();//this method returns a Node in the topology
action.dstIp = server.ip();
action.dstMac = server.mac();
action.outputPort = server.connectedPort();
pushFlowMod(match,action,PacketType.PACKET_IN);
TcpUdpPort srcPort = match.srcPort;
match.srcPort = match.dstPort;
match.dstPort = srcPort;
action.outputPort = match.inputPort;
match.dstIp = match.srcIp;
match.srcIp = server.ip();
action.srcIp = server.ip();
action.srcMac = server.mac();
return pushFlowMod(match,action,PacketType.PACKET_OUT);
}
private boolean pushFlowMod(MatchFields match, ActionFields action, PacketType packet) {
OfmMutableFlowMod flowMod;
flowMod = (OfmMutableFlowMod) MessageFactory.create(pv, MessageType.FLOW_MOD);
flowMod.match((Match) createMatch(match).toImmutable());
flowMod.hardTimeout(0);
flowMod.idleTimeout(flowTimeout);
flowMod.priority(flowPriority);
flowMod.command(FlowModCommand.ADD);
flowMod.bufferId(BufferId.NO_BUFFER);
flowMod.outPort(Port.NONE);
flowMod.cookie(0x1234);
flowMod.flowModFlags(flags);
flowMod.addAction(ActionFactory
.createAction(pv, ActionType.OUTPUT, action.outputPort, ActOutput.CONTROLLER_NO_BUFFER));
if(packet == PacketType.PACKET_OUT){
flowMod.addAction(createActionSetField(pv,OxmBasicFieldType.ETH_SRC, action.srcMac))
.addAction(createActionSetField(pv,OxmBasicFieldType.IPV4_SRC, action.srcIp));
}
else
{
flowMod.addAction(createActionSetField(pv,OxmBasicFieldType.ETH_DST, action.dstMac))
.addAction(createActionSetField(pv,OxmBasicFieldType.IPV4_DST, action.dstIp));
}
try {
return controllerService.sendFlowMod((OfmFlowMod) flowMod.toImmutable(),action.dataPathId).setSuccess();
} catch (OpenflowException e) {
e.printStackTrace();
}
return false;
}
private MutableMatch createMatch(MatchFields matchField){
MutableMatch match = MatchFactory.createMatch(pv).
addField(createBasicField(pv, OxmBasicFieldType.ETH_TYPE,EthernetType.IPv4))
.addField(createBasicField(pv, OxmBasicFieldType.IP_PROTO,IpProtocol.TCP))
//.addField(createBasicField(pv, OxmBasicFieldType.IN_PORT,matchField.inputPort))
.addField(createBasicField(pv, OxmBasicFieldType.IPV4_SRC,matchField.srcIp))
.addField(createBasicField(pv, OxmBasicFieldType.IPV4_DST,matchField.dstIp))
.addField(createBasicField(pv, IpProtocol.TCP.equals(IpProtocol.TCP)
? OxmBasicFieldType.TCP_SRC : (OxmBasicFieldType.UDP_SRC),PortNumber.valueOf(matchField.srcPort.getNumber())))
.addField(createBasicField(pv, IpProtocol.TCP.equals(IpProtocol.TCP)
? OxmBasicFieldType.TCP_DST : OxmBasicFieldType.UDP_DST,PortNumber.valueOf(matchField.dstPort.getNumber())));
return match;
}
private class MatchFields {
public BigPortNumber outputPort;
public BigPortNumber inputPort;
public IpAddress srcIp;
public IpAddress dstIp;
public MacAddress srcMac;
public MacAddress dstMac;
public TcpUdpPort srcPort;
public TcpUdpPort dstPort;
}
private class ActionFields {
public BigPortNumber outputPort;
public DataPathId dataPathId;
public IpAddress srcIp;
public IpAddress dstIp;
public MacAddress srcMac;
public MacAddress dstMac;
}
}
Thanks