2 * Copyright (c) 2016 NEC Corporation and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.services;
11 import java.math.BigInteger;
12 import java.util.ArrayList;
13 import java.util.List;
14 import org.opendaylight.netvirt.openstack.netvirt.api.L2ForwardingLearnProvider;
15 import org.opendaylight.netvirt.openstack.netvirt.api.LearnConstants;
16 import org.opendaylight.netvirt.openstack.netvirt.api.LearnConstants.LearnFlowModsType;
17 import org.opendaylight.netvirt.openstack.netvirt.providers.ConfigInterface;
18 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
19 import org.opendaylight.netvirt.openstack.netvirt.providers.openflow13.Service;
20 import org.opendaylight.netvirt.utils.mdsal.openflow.FlowUtils;
21 import org.opendaylight.netvirt.utils.mdsal.openflow.MatchUtils;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.Action;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionKey;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.InstructionsBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCase;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.ApplyActionsCaseBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActions;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.apply.actions._case.ApplyActionsBuilder;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionKey;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModAddMatchFromFieldCaseBuilder;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModAddMatchFromValueCaseBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModCopyFieldIntoFieldCaseBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModCopyValueIntoFieldCaseBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.FlowModOutputToPortCaseBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.flow.mod.add.match.from.field._case.FlowModAddMatchFromFieldBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.flow.mod.add.match.from.value._case.FlowModAddMatchFromValueBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.flow.mod.copy.field.into.field._case.FlowModCopyFieldIntoFieldBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.flow.mod.copy.value.into.field._case.FlowModCopyValueIntoFieldBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.flow.mod.spec.flow.mod.spec.flow.mod.output.to.port._case.FlowModOutputToPortBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nodes.node.table.flow.instructions.instruction.instruction.apply.actions._case.apply.actions.action.action.NxActionLearnNodesNodeTableFlowApplyActionsCaseBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.NxLearnBuilder;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.nx.learn.FlowMods;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.nx.action.learn.grouping.nx.learn.FlowModsBuilder;
50 import org.osgi.framework.BundleContext;
51 import org.osgi.framework.ServiceReference;
52 import org.slf4j.Logger;
53 import org.slf4j.LoggerFactory;
55 public class L2ForwardingLearnService extends AbstractServiceInstance implements ConfigInterface, L2ForwardingLearnProvider {
56 private static final Logger LOG = LoggerFactory.getLogger(L2ForwardingLearnService.class);
58 public L2ForwardingLearnService() {
59 super(Service.L2_LEARN);
62 public L2ForwardingLearnService(Service service) {
67 * (Table:L2ForwardingLearn) Remote Tep Learning
68 * Match: reg0 = ClassifierService.REG_VALUE_FROM_REMOTE
69 * Action: learn and goto next table
70 * table=105,reg0=0x2 actions=learn(table=110,hard_timeout=300,priority=16400,NXM_NX_TUN_ID[],NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[],output:NXM_OF_IN_PORT[]),goto_table:110
73 public void programL2ForwardingLearnRule(Long dpidLong) {
74 NodeBuilder nodeBuilder = FlowUtils.createNodeBuilder(dpidLong);
75 FlowBuilder flowBuilder = new FlowBuilder();
76 String flowName = "L2ForwardingLearn";
77 FlowUtils.initFlowBuilder(flowBuilder, flowName, getTable());
78 List<Action> listAction = new ArrayList<>();
80 MatchBuilder matchBuilder = new MatchBuilder();
81 MatchUtils.addNxRegMatch(matchBuilder, new MatchUtils.RegMatch(ClassifierService.REG_FIELD, ClassifierService.REG_VALUE_FROM_REMOTE));
82 flowBuilder.setMatch(matchBuilder.build());
84 // Create learn action
88 * 0 1 2 3 4 5 6 7 idleTO hardTO prio cook flags table finidle finhard
91 * 0 1 2 3 learnFlowModType srcField dstField FlowModNumBits
93 String[] header = new String[] {
94 "0", "300", "16400", "0", "0", "110", "0", "0"
97 String[][] flowMod = new String[3][];
99 flowMod[0] = new String[] { LearnConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
100 LearnConstants.NxmOfFieldType.NXM_NX_TUN_ID.getHexType(),
101 LearnConstants.NxmOfFieldType.NXM_NX_TUN_ID.getHexType(),
102 LearnConstants.NxmOfFieldType.NXM_NX_TUN_ID.getFlowModHeaderLen() };
103 // NXM_OF_ETH_DST[]=NXM_OF_ETH_SRC[]
104 flowMod[1] = new String[] { LearnConstants.LearnFlowModsType.MATCH_FROM_FIELD.name(),
105 LearnConstants.NxmOfFieldType.NXM_OF_ETH_SRC.getHexType(),
106 LearnConstants.NxmOfFieldType.NXM_OF_ETH_DST.getHexType(),
107 LearnConstants.NxmOfFieldType.NXM_OF_ETH_DST.getFlowModHeaderLen()};
108 // output:NXM_OF_IN_PORT[]
109 flowMod[2] = new String[] { LearnConstants.LearnFlowModsType.OUTPUT_TO_PORT.name(),
110 LearnConstants.NxmOfFieldType.NXM_OF_IN_PORT.getHexType(),
111 LearnConstants.NxmOfFieldType.NXM_OF_IN_PORT.getFlowModHeaderLen() };
113 listAction.add(buildAction(0, header, flowMod));
115 ApplyActions applyActions = new ApplyActionsBuilder().setAction(listAction).build();
116 ApplyActionsCase applyActionsCase = new ApplyActionsCaseBuilder().setApplyActions(applyActions).build();
117 InstructionsBuilder instructionsBuilder = new InstructionsBuilder();
118 InstructionBuilder instructionBuilder = new InstructionBuilder();
119 List<Instruction> instructions = new ArrayList<>();
121 instructionBuilder.setInstruction(applyActionsCase);
122 instructionBuilder.setOrder(0);
123 instructionBuilder.setKey(new InstructionKey(0));
124 instructions.add(instructionBuilder.build());
126 // Next service GOTO Instructions Need to be appended to the List
127 instructionBuilder = this.getMutablePipelineInstructionBuilder();
128 instructionBuilder.setOrder(1);
129 instructionBuilder.setKey(new InstructionKey(1));
130 instructions.add(instructionBuilder.build());
132 // Add InstructionBuilder to the Instruction(s)Builder List
133 instructionsBuilder.setInstruction(instructions);
135 // Add InstructionsBuilder to FlowBuilder
136 flowBuilder.setInstructions(instructionsBuilder.build());
138 writeFlow(flowBuilder, nodeBuilder);
145 * copy from org.opendaylight.genius.mdsalutil.ActionType.learn
147 private Action buildAction(int newActionKey, String[] header, String[][] actionValues) {
148 NxLearnBuilder learnBuilder = new NxLearnBuilder();
149 learnBuilder.setIdleTimeout(Integer.parseInt(header[0]));
150 learnBuilder.setHardTimeout(Integer.parseInt(header[1]));
151 learnBuilder.setPriority(Integer.parseInt(header[2]));
152 learnBuilder.setCookie(BigInteger.valueOf(Long.valueOf(header[3])));
153 learnBuilder.setFlags(Integer.parseInt(header[4]));
154 learnBuilder.setTableId(Short.parseShort(header[5]));
155 learnBuilder.setFinIdleTimeout(Integer.parseInt(header[6]));
156 learnBuilder.setFinHardTimeout(Integer.parseInt(header[7]));
158 List<FlowMods> flowModsList = new ArrayList<>();
159 for(String[] values : actionValues) {
160 if(LearnFlowModsType.MATCH_FROM_FIELD.name().equals(values[0])) {
161 FlowModAddMatchFromFieldBuilder builder = new FlowModAddMatchFromFieldBuilder();
162 builder.setSrcField(Long.decode(values[1]));
163 builder.setSrcOfs(0);
164 builder.setDstField(Long.decode(values[2]));
165 builder.setDstOfs(0);
166 builder.setFlowModNumBits(Integer.parseInt(values[3]));
168 FlowModsBuilder flowModsBuilder = new FlowModsBuilder();
169 FlowModAddMatchFromFieldCaseBuilder caseBuilder = new FlowModAddMatchFromFieldCaseBuilder();
170 caseBuilder.setFlowModAddMatchFromField(builder.build());
171 flowModsBuilder.setFlowModSpec(caseBuilder.build());
172 flowModsList.add(flowModsBuilder.build());
173 } else if (LearnFlowModsType.MATCH_FROM_VALUE.name().equals(values[0])) {
174 FlowModAddMatchFromValueBuilder builder = new FlowModAddMatchFromValueBuilder();
175 builder.setValue(Integer.parseInt(values[1]));
176 builder.setSrcField(Long.decode(values[2]));
177 builder.setSrcOfs(0);
178 builder.setFlowModNumBits(Integer.parseInt(values[3]));
180 FlowModsBuilder flowModsBuilder = new FlowModsBuilder();
181 FlowModAddMatchFromValueCaseBuilder caseBuilder = new FlowModAddMatchFromValueCaseBuilder();
182 caseBuilder.setFlowModAddMatchFromValue(builder.build());
183 flowModsBuilder.setFlowModSpec(caseBuilder.build());
184 flowModsList.add(flowModsBuilder.build());
185 } else if (LearnFlowModsType.COPY_FROM_FIELD.name().equals(values[0])) {
186 FlowModCopyFieldIntoFieldBuilder builder = new FlowModCopyFieldIntoFieldBuilder();
187 builder.setSrcField(Long.decode(values[1]));
188 builder.setSrcOfs(0);
189 builder.setDstField(Long.decode(values[2]));
190 builder.setDstOfs(0);
191 builder.setFlowModNumBits(Integer.parseInt(values[3]));
193 FlowModsBuilder flowModsBuilder = new FlowModsBuilder();
194 FlowModCopyFieldIntoFieldCaseBuilder caseBuilder = new FlowModCopyFieldIntoFieldCaseBuilder();
195 caseBuilder.setFlowModCopyFieldIntoField(builder.build());
196 flowModsBuilder.setFlowModSpec(caseBuilder.build());
197 flowModsList.add(flowModsBuilder.build());
198 } else if (LearnFlowModsType.COPY_FROM_VALUE.name().equals(values[0])) {
199 FlowModCopyValueIntoFieldBuilder builder = new FlowModCopyValueIntoFieldBuilder();
200 builder.setValue(Integer.parseInt(values[1]));
201 builder.setDstField(Long.decode(values[2]));
202 builder.setDstOfs(0);
203 builder.setFlowModNumBits(Integer.parseInt(values[3]));
205 FlowModsBuilder flowModsBuilder = new FlowModsBuilder();
206 FlowModCopyValueIntoFieldCaseBuilder caseBuilder = new FlowModCopyValueIntoFieldCaseBuilder();
207 caseBuilder.setFlowModCopyValueIntoField(builder.build());
208 flowModsBuilder.setFlowModSpec(caseBuilder.build());
209 flowModsList.add(flowModsBuilder.build());
210 } else if (LearnFlowModsType.OUTPUT_TO_PORT.name().equals(values[0])) {
211 FlowModOutputToPortBuilder builder = new FlowModOutputToPortBuilder();
212 builder.setSrcField(Long.decode(values[1]));
213 builder.setSrcOfs(0);
214 builder.setFlowModNumBits(Integer.parseInt(values[2]));
216 FlowModsBuilder flowModsBuilder = new FlowModsBuilder();
217 FlowModOutputToPortCaseBuilder caseBuilder = new FlowModOutputToPortCaseBuilder();
218 caseBuilder.setFlowModOutputToPort(builder.build());
219 flowModsBuilder.setFlowModSpec(caseBuilder.build());
220 flowModsList.add(flowModsBuilder.build());
223 learnBuilder.setFlowMods(flowModsList);
225 ActionBuilder abExt = new ActionBuilder();
226 abExt.setKey(new ActionKey(newActionKey));
228 abExt.setAction(new NxActionLearnNodesNodeTableFlowApplyActionsCaseBuilder()
229 .setNxLearn(learnBuilder.build()).build());
230 return abExt.build();
234 public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
235 super.setDependencies(bundleContext.getServiceReference(L2ForwardingLearnProvider.class.getName()), this);
239 public void setDependencies(Object impl) {