Ask is moving to Stack Overflow and Serverfault.com! Please use the "opendaylight" tag on either of these sites. This site is now in Read-Only mode

0

Flow that redirects to a flow table

asked 2017-08-24 09:41:08 -0800

VincentJahjah gravatar image

I've installed a few rules on my switches, and one specific rule doesn't seem to behave as intended. Here are the relevant flows:

s3 ovs-ofctl dump-flows \s3

..., table=0, n_packets=462, n_bytes=45276, idle_age=4, priority=108,ip,in_port=1 actions=TABLE
..., table=2, n_packets=0, n_bytes=0, idle_age=99, priority=1002,ip,nw_src=0.0.0.0/0.0.0.3 actions=TABLE
..., table=2, n_packets=0, n_bytes=0, idle_age=99, priority=1002,ip,nw_src=0.0.0.1/0.0.0.3 actions=TABLE
..., table=2, n_packets=0, n_bytes=0, idle_age=99, priority=1002,ip,nw_src=0.0.0.2/0.0.0.3 actions=TABLE
..., table=2, n_packets=0, n_bytes=0, idle_age=99, priority=1002,ip,nw_src=0.0.0.3/0.0.0.3 actions=TABLE

While it's not shown here, the first forwarding rule should normally forward to Table 2, and since the rules on table 2 match the entire spectrum of possible IP addresses, it doesn't make sense that the rules on table 2 would match no packets whereas the first rule has matched 462 packets. Note that all of these rules match ipv4 packets only.

My hypothesis is that the exact detail of forwarding to Table 2 has been lost because I did something wrong.

Here's an extract of my code to build these rules (OutputAction is a costum defined enum):

ApplyActionsBuilder applyActionsBuilder = new ApplyActionsBuilder();
...
if (outputAction.equals(OutputAction.TO_TABLE)) {
    applyActionsBuilder.setAction(ImmutableList.of(getSendToTableAction()));
}
...
ApplyActions applyActions = applyActionsBuilder.build();
InstructionBuilder instructionBuilder = new InstructionBuilder().setOrder(0);
if (outputAction.equals(OutputAction.TO_TABLE)) {
    GoToTable goToTable = new GoToTableBuilder().setTableId(goToTableId).build();
    instructionBuilder.setInstruction(new GoToTableCaseBuilder().setGoToTable(goToTable).build());
}
Instruction applyActionsInstruction = instructionBuilder.setInstruction(
                            new ApplyActionsCaseBuilder().setApplyActions(applyActions).build())
                                         .build();

Note that "GoToTableId" is a Short containing the ID of the table to go to (it is 2 in the context of the above rule).

Here is the code for the "sendToTableAction", which appears to work correctly since this part does transpire in ovs-ofctl.

private static Action getSendToTableAction() {
    Uri destPortUri = new Uri(OutputPortValues.TABLE.toString());
    Action sendToController = new ActionBuilder().setOrder(0).setKey(new ActionKey(0))
            .setAction(new OutputActionCaseBuilder().setOutputAction(
                       new OutputActionBuilder().setMaxLength(0xffff)
                                                .setOutputNodeConnector(destPortUri).build())
                       .build()).build();

    return sendToController;
}

So, my question is: why do the rules on table 2 not match any packet?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2017-08-24 18:55:08 -0800

VincentJahjah gravatar image

updated 2017-08-25 07:09:56 -0800

Answering my own question.

It turns out that "OutputActionCase" and "GoToTableCase" are two separate "cases" of actions that can be added to an instruction. I think the problem is that I am doing two things at once but pretending that I am doing only one, and OpenFlow is confused by that.

My solution involved dropping the "getSendToTableAction" altogether. For some reason, "outputing to TABLE" had no obvious effect. With "OutputActionCase" out of the equation, the "GoToTableCase" can do its thing.

Below is my code. It should give enough details to answer the question:

    ApplyActionsBuilder applyActionsBuilder = new ApplyActionsBuilder();

    if (outputAction.equals(OutputAction.NO_ACTION)) {
        //No actions
    } else if (outputAction.equals(OutputAction.TO_PORT)) {
        applyActionsBuilder.setAction(ImmutableList.of(getSendToPortAction(destPort)));
    } else if (outputAction.equals(OutputAction.TO_CONTROLLER)) {
        applyActionsBuilder.setAction(ImmutableList.of(getSendToControllerAction()));
    } else if (outputAction.equals(OutputAction.TO_TABLE)) {
        //No actions
    } else if (outputAction.equals(OutputAction.RENAME_DEST_IP)) {
        applyActionsBuilder.setAction(ImmutableList.of(getRenameDestIpAction(renameAddress)));
    } else if (outputAction.equals(OutputAction.RENAME_SRC_IP)) {
        applyActionsBuilder.setAction(ImmutableList.of(getRenameSrcIpAction(renameAddress)));
    } else {
        throw new RuntimeException("makeFlowBody, Error, bug, unidentified OutputAction");
    }

    // Wrap Apply Action in an Instruction
    InstructionBuilder instructionBuilder = new InstructionBuilder().setOrder(0);

    if (outputAction.equals(OutputAction.TO_TABLE)) {
        GoToTable goToTable = new GoToTableBuilder().setTableId(goToTableId).build();
        instructionBuilder.setInstruction(new GoToTableCaseBuilder().setGoToTable(goToTable).build());
    } else {
        ApplyActions applyActions = applyActionsBuilder.build();
        instructionBuilder.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(applyActions).build());
    }
    Instruction instruction = instructionBuilder.build();

And here are what my flows look like, as expected:

..., table=0, n_packets=3156, n_bytes=3155260, ...,ip,in_port=1 actions=resubmit(,2)
..., table=2, n_packets=3156, n_bytes=3155260, ...,ip,nw_src=0.0.0.0/0.0.0.3 actions=resubmit(,3)
..., table=2, n_packets=0, n_bytes=0, ...,ip,nw_src=0.0.0.1/0.0.0.3 actions=resubmit(,4)
..., table=2, n_packets=0, n_bytes=0, ...,ip,nw_src=0.0.0.2/0.0.0.3 actions=resubmit(,5)
..., table=2, n_packets=0, n_bytes=0, ...,ip,nw_src=0.0.0.3/0.0.0.3 actions=resubmit(,6)
edit flag offensive delete publish link more
Login/Signup to Answer

Question Tools

Follow
1 follower

Stats

Asked: 2017-08-24 09:41:08 -0800

Seen: 19 times

Last updated: Aug 25