# Send packet to switch and back to controller

I am trying to create a latency-monitoring system by sending special ping-like packets from the controller.

TransmitPacketInput input = new TransmitPacketInputBuilder().setNode(nodeRef(node.getId()))
.setEgress(nodeConnectorRef(node.getId(), egress))
.build();
packetProcessingService.transmitPacket(input);


The thing is, because my PINGs are from the controller to the controller, I need to compute the latencies of links individually, and I also need to calculate the latency of a link from the controller to the switch. This mean my packet must do this:

Controller - Switch - Controller

I've tried a few things, but none have really worked. What I have learned is that if I "setEgress", then the packet will immediately be forwarded out of the port, regardless of the flow rules installed on the switch.

As a result, I have two options, but I don't know if I can do either:

1. I could send the packet with "egress" set to the controller port. (But which port is that?)
2. I could find a way to let the flow rules decide of the output port, and NOT "egress". So far every time I tried not setting egress, I have gotten errors on the "transmitPacket" call, with "input" being apparently null.

Are either of those possible?

PS: Incidentally, I have no idea what "setIngress" does...

edit retag close merge delete

Sort by » oldest newest most voted

So, I learned that I could in fact create NodeConnectorIds (or TpIds, I presume) with the value of OpenFlow's reserved ports as the string. The values are given here, and a more detailed description of those values can be found here.

Sending packet directly to controller: Use the CONTROLLER port value.

Sending the packet to table 0 where it will then be processed: Use the TABLE port value. This is where "setIngress" comes into play: this will set the port from which the packet will be presumed to have come (useful if you have flow rules matching the in-port).

Here is an example:

public final static NodeConnectorId TABLE_PORT = new NodeConnectorId("0xfffffff9");
...
// Output from the ingress port, so the packet is processed from tables
NodeConnectorId egress = TABLE_PORT;
// The first port, because it'll usually exist
NodeConnectorId ingress = new NodeConnectorId(node.getId().getValue() + ":1");
TransmitPacketInput input = new  TransmitPacketInputBuilder()
.setNode(MDSalAccessUtils.nodeRef(node.getId()))
.setEgress(MDSalAccessUtils.nodeConnectorRef(node.getId(), egress))
.setIngress(MDSalAccessUtils.nodeConnectorRef(node.getId(), ingress))
.build();


and

public final static NodeConnectorId CONTROLLER_PORT = new NodeConnectorId("0xfffffffd");
...
// Output from the ingress port, so the packet is processed from tables
NodeConnectorId egress = CONTROLLER_PORT ;
// The first port, because it'll usually exist
TransmitPacketInput input = new  TransmitPacketInputBuilder()
.setNode(MDSalAccessUtils.nodeRef(node.getId()))
.setEgress(MDSalAccessUtils.nodeConnectorRef(node.getId(), egress))
.build();