【问题标题】:How to create a set vlan flow?如何创建一组 vlan 流?
【发布时间】:2017-12-02 17:23:22
【问题描述】:

我想做相当于以下的事情:

sudo ovs-ofctl add-flow s1 table=2,metadata=1379878762,actions=push_vlan:0x8100,mod_vlan_vid:4000,output:6,goto_table:4 -O openflow13

如何在 opendaylight java 代码中执行此操作?我根据我能找到的一些示例进行了尝试,但没有出现流,或者有时通过足够的调整,我可以让流的一部分出现(我永远看不到输出动作)。我正在使用 Carbon(最新版本的 carbon)进行开发。是否值得切换到夜间快照?

当我使用 opendaylight 执行此操作时,我发现与 vlan 相关的任何操作都不会出现在我的流程中。只有 goto 出现在流程中。

=== 更新 ===

我使用以下java代码来设置和创建vlan标签(由下面的答案建议):

    private static Instruction createSetVlanAndOutputToPortInstructions( int vlanId,
        String outputPortUri) {

    List<Action> actionList = new ArrayList<>();
    ActionBuilder ab = new ActionBuilder();

    Integer VLAN_ETHERTYPE = 0x8100;
    ActionBuilder actionBuilder = new ActionBuilder();

    //push vlan
    Action pushVlanAction = actionBuilder
        .setOrder(0).setAction(new PushVlanActionCaseBuilder()
            .setPushVlanAction(new PushVlanActionBuilder()
                .setEthernetType(VLAN_ETHERTYPE)
                    .build())
                    .build())
                .build();
    actionList.add(pushVlanAction);

    //set vlan id

    SetVlanIdActionBuilder tab = new SetVlanIdActionBuilder();
    tab.setVlanId(new VlanId((int) vlanId));
    SetVlanIdActionCaseBuilder vidcb = new SetVlanIdActionCaseBuilder();
    vidcb.setSetVlanIdAction(tab.build());
    Action setVlanIdAction = actionBuilder.setOrder(1).setAction(vidcb.build()).build();



    OutputActionBuilder output = new OutputActionBuilder();
    output.setMaxLength(Integer.valueOf(0xffff));

    Uri controllerPort = new Uri(outputPortUri);
    output.setOutputNodeConnector(controllerPort);

    ab = new ActionBuilder();
    ab.setKey(new ActionKey(0));
    ab.setAction(new OutputActionCaseBuilder().setOutputAction(output.build()).build());
    ab.setOrder(2);
    actionList.add(ab.build());

    ApplyActionsBuilder aab = new ApplyActionsBuilder();

    aab.setAction(actionList);

    InstructionBuilder ib = new InstructionBuilder();
    ib.setKey(new InstructionKey(0));
    ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());

    return ib.build();
}

创建流规则的代码在这里:

 FlowBuilder tagPacketFlow = new FlowBuilder().setTableId((short) tableId)
            .setFlowName("metadataMatchSetVlanTagSendToPortAndGoToStripVlanTagTable").setId(flowId)
            .setKey(new FlowKey(flowId)).setCookie(flowCookie);
    MatchBuilder matchBuilder = new MatchBuilder();
    createMetadataMatch(matchBuilder, flowCookie.getValue());

    InstructionBuilder ib = new InstructionBuilder();
    Instruction createVlanTag = FlowUtils.createSetVlanAndOutputToPortInstructions(
            SdnMudConstants.MUD_RULE_HIT_LABEL, outputPortUri);

    InstructionsBuilder insb = new InstructionsBuilder();
    ArrayList<Instruction> instructions = new ArrayList<Instruction>();
    instructions.add(createVlanTag);
    Instruction gotoInstruction = ib.setInstruction(new GoToTableCaseBuilder()
            .setGoToTable(new GoToTableBuilder().setTableId(SdnMudConstants.STRIP_VLAN_RULE_TABLE).build()).build())
            .setOrder(3)
            .setKey(new InstructionKey(0)).build();
    instructions.add(gotoInstruction);

    insb.setInstruction(instructions);
    tagPacketFlow.setMatch(matchBuilder.build()).setInstructions(insb.build())
            .setPriority(35).setBufferId(OFConstants.ANY)
            .setHardTimeout(time).setIdleTimeout(0).setFlags(new FlowModFlags(false, false, false, false, false));

在调用代码时,我在 openvswitch 中看到了这一点:

 cookie=0x523f476a, duration=0.012s, table=2, n_packets=0, n_bytes=0, hard_timeout=30000, priority=35,metadata=0x523f476a actions=goto_table:3

以下是与此流程对应的配置数据存储区中的转储:

    {
                        "buffer_id": 4294967295,
                        "cookie": 1379878762,
                        "flags": "",
                        "flow-name": "metadataMatchSetVlanTagSendToPortAndGoToStripVlanTagTable",
                        "hard-timeout": 30000,
                        "id": "toaster.nist.gov/42",
                        "idle-timeout": 0,
                        "instructions": {
                            "instruction": [
                                {
                                    "go-to-table": {
                                        "table_id": 3
                                    },
                                    "order": 0
                                }
                            ]
                        },
                        "match": {
                            "metadata": {
                                "metadata": 1379878762
                            }
                        },
                        "priority": 35,
                        "table_id": 2
                    }

所以 Vlan 设置就消失了。

==== 结束更新 ====

==== 更新 1 ====

我在提交事务之前记录了流程。这是设置 VLAN 的说明:

   ApplyActionsCase [_applyActions=ApplyActions 
      [_action=[Action [_action=PushVlanActionCase 
      [_pushVlanAction=PushVlanAction [_ethernetType=33024,
      _vlanId=VlanId [_value=1001], augmentation=[]], augmentation=[]], 
     _key=ActionKey [_order=0], _order=0, augmentation=[]], 
      Action [_action=SetVlanIdActionCase[_setVlanIdAction=SetVlanIdAction
     [_vlanId=VlanId [_value=1001], augmentation=[]], 
     augmentation=[]], _key=ActionKey [_order=1], _order=1, 
     augmentation=[]], Action [_action=OutputActionCase 
     [_outputAction=OutputAction [_maxLength=65535,
     _outputNodeConnector=Uri [_value=openflow:1:6], 
      augmentation=[]], augmentation=[]], 
     _key=ActionKey [_order=2], _order=2,
      augmentation=[]]], augmentation=[]], augmentation=[]]

我看不出有什么问题。

=== 结束更新 1 ===

=== 更新 2 ===

当我删除 goto 并在此处遵循 xml 的模式时: https://wiki.opendaylight.org/view/Editing_OpenDaylight_OpenFlow_Plugin:End_to_End_Flows:Example_Flows#Push_VLAN

它只能在没有 goto 的情况下工作。换句话说,如果我删除 goto,我可以在配置数据存储中看到推送流。如果我把 goto 放进去,只会出现 goto。

==== 结束更新 2 ====

我在问题跟踪器中看到一个关于 opendaylight soutbound 中的 vlan 流被破坏的问题,但它似乎已在 2014 年修复(?)。

这是在氮气中固定的吗?我该如何提交针对 opendaylight 的错误?

【问题讨论】:

    标签: openflow opendaylight


    【解决方案1】:

    试试这个:

    Integer VLAN_ETHERTYPE = 0x8100;
    ActionBuilder actionBuilder = new ActionBuilder();
    List<Action> actions = new ArrayList<>();
    
    //push vlan
    Action pushVlanAction = actionBuilder
        .setOrder(0).setAction(new PushVlanActionCaseBuilder()
            .setPushVlanAction(new PushVlanActionBuilder()
                .setEthernetType(VLAN_ETHERTYPE)
                    .build())
                    .build())
                .build();
    actions.add(pushVlanAction);
    
    //set vlan id
    Action setVlanIdAction = actionBuilder
        .setOrder(1).setAction(new SetFieldCaseBuilder()
            .setSetField(new SetFieldBuilder()
                .setVlanMatch(new VlanMatchBuilder()
                    .setVlanId(new VlanIdBuilder()
                        .setVlanId(new VlanId(vlanID))
                         .setVlanIdPresent(true)
                    .build())
                .build())
            .build())
        .build())
        .build();
    actions.add(setVlanIdAction);
    

    然后,您需要通过以下方式将您的操作添加到您的指令中:

    //ApplyActions
    ApplyActions applyActions = new ApplyActionsBuilder().setAction(actions).build();
    
    //Instruction
    Instruction applyActionsInstruction = new InstructionBuilder() 
            .setOrder(0).setInstruction(new ApplyActionsCaseBuilder()
                    .setApplyActions(applyActions) 
                    .build()) 
                .build();
    

    也可以看看here

    【讨论】:

    • 不幸的是没有工作。我的表还有:cookie=0x523f476a, duration=0.012s, table=2, n_packets=0, n_bytes=0, hard_timeout=30000, priority=35,metadata=0x523f476a actions=goto_table:3 .
    • 为什么 setField 需要一个 VlanMatchBuilder() ?我对编程模型感到困惑。
    • @LostInTheFrequencyDomain 我认为您没有在说明中正确添加 Vlan 操作...请参阅我编辑的帖子以了解如何添加它们。至于你的第二个问题,我也不知道,我在教程中发现是这样的。
    • @LostInTheFrequencyDomain 实际上我找到了另一个示例,请参阅我编辑的帖子。
    • Carbon 中存在(我相信)一个导致上述行为的错误。将代码升级到 Nitrogen 后,我能够创建这样的流程。感谢您的帮助。
    【解决方案2】:

    升级到 Nitrogen 后,我发现我的问题消失了。因此,Carbon 版本中似乎存在错误。不知道什么时候修好的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-04-22
      • 2021-03-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多