import java.math.BigInteger;
import java.util.List;
+import org.opendaylight.ovsdb.openstack.netvirt.api.IngressAclProvider;
import org.opendaylight.ovsdb.openstack.netvirt.api.L2ForwardingProvider;
+import org.opendaylight.ovsdb.openstack.netvirt.providers.ConfigInterface;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.AbstractServiceInstance;
import org.opendaylight.ovsdb.openstack.netvirt.providers.openflow13.Service;
import org.opendaylight.ovsdb.utils.mdsal.openflow.ActionUtils;
import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.NodeBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.l2.types.rev130827.VlanId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowplugin.extension.nicira.action.rev140714.dst.choice.grouping.dst.choice.DstNxRegCaseBuilder;
+import org.osgi.framework.BundleContext;
+import org.osgi.framework.ServiceReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
-public class L2ForwardingService extends AbstractServiceInstance implements L2ForwardingProvider {
+public class L2ForwardingService extends AbstractServiceInstance implements ConfigInterface, L2ForwardingProvider {
private static final Logger logger = LoggerFactory.getLogger(L2ForwardingService.class);
public L2ForwardingService() {
super(Service.L2_FORWARDING);
/**
- * Utility funcion used by the flooding logic to allow a flow to be resubmitted
+ * Utility function used by the flooding logic to allow a flow to be resubmitted
* to the local port flooding rule, after being outputed to all available tunnel
* or VLAN egress ports.
*/
*/
@Override
- public void programLocalVlanBcastOut(Long dpidLong,
- String segmentationId, Long localPort, Long ethPort, boolean write) {
+ public void programLocalVlanBcastOut(Long dpidLong, String segmentationId,
+ Long localPort, Long ethPort, boolean write) {
String nodeName = OPENFLOW + dpidLong;
}
}
}
- logger.info("VlanBcastOut_ addNew= {}", addNew);
+
if (addNew) {
ActionBuilder ab = new ActionBuilder();
// Add InstructionsBuilder to FlowBuilder
flowBuilder.setInstructions(isb.build());
-
writeFlow(flowBuilder, nodeBuilder);
} else {
//boolean flowRemove = removeOutputPortFromGroup(nodeBuilder, ib, dpidLong,
// localPort, existingInstructions);
- boolean flowRemove = InstructionUtils.removeOutputPortFromInstructions(ib, dpidLong,
- localPort, existingInstructions);
+ boolean flowRemove = removeOutputPortFromInstructions(ib, dpidLong, localPort, ethPort,
+ existingInstructions);
if (flowRemove) {
/* if all ports are removed, remove flow */
removeFlow(flowBuilder, nodeBuilder);
}
}
+ private boolean removeOutputPortFromInstructions(InstructionBuilder ib, Long dpidLong, Long localPort,
+ Long ethPort, List<Instruction> instructions) {
+ List<Action> actionList = Lists.newArrayList();
+ boolean removeFlow = true;
+
+ if (instructions != null) {
+ ApplyActionsCase aac = (ApplyActionsCase) ib.getInstruction();
+ Instruction in = instructions.get(0);
+ List<Action> oldActionList = (((ApplyActionsCase) in.getInstruction()).getApplyActions().getAction());
+ NodeConnectorId ncid = new NodeConnectorId(OPENFLOW + dpidLong + ":" + localPort);
+ NodeConnectorId ncidEth = new NodeConnectorId(OPENFLOW + dpidLong + ":" + ethPort);
+
+ // Remove the port from the output list
+ ActionBuilder ab = new ActionBuilder();
+ int index = 2;
+ //for (ListIterator<Action> it = oldActionList.listIterator(oldActionList.size()); it.hasPrevious();) {
+ // Action action = it.previous();
+ for (Action action : oldActionList) {
+ if (action.getAction() instanceof OutputActionCase) {
+ OutputActionCase opAction = (OutputActionCase) action.getAction();
+ if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncidEth))) {
+ actionList.add(action);
+ } else if (opAction.getOutputAction().getOutputNodeConnector().equals(new Uri(ncid)) == false) {
+ ab.setAction(action.getAction());
+ ab.setOrder(index);
+ ab.setKey(new ActionKey(index));
+ actionList.add(ab.build());
+ index++;
+ }
+ } else {
+ actionList.add(action);
+ }
+ }
+ ApplyActionsBuilder aab = new ApplyActionsBuilder();
+ aab.setAction(actionList);
+ ib.setInstruction(new ApplyActionsCaseBuilder().setApplyActions(aab.build()).build());
+ }
+
+ if (actionList != null && actionList.size() > 2) {
+ // Add InstructionBuilder to the Instruction(s)Builder List
+ InstructionsBuilder isb = new InstructionsBuilder();
+ isb.setInstruction(instructions);
+ removeFlow = false;
+ }
+
+ return removeFlow;
+ }
+
/*
* (Table:1) Local Table Miss
* Match: Any Remaining Flows w/a TunID
flowBuilder.setBarrier(true);
flowBuilder.setTableId(getTable());
flowBuilder.setKey(key);
- flowBuilder.setPriority(16384);
+ flowBuilder.setPriority(16383); // FIXME: change it back to 16384 once bug 3005 is fixed.
flowBuilder.setFlowName(flowId);
flowBuilder.setHardTimeout(0);
flowBuilder.setIdleTimeout(0);
logger.debug("createOutputPortInstructions() : applyAction {}", aab.build());
return ib;
}
+
+ @Override
+ public void setDependencies(BundleContext bundleContext, ServiceReference serviceReference) {
+ super.setOrchestrator(bundleContext.getServiceReference(L2ForwardingProvider.class.getName()), this);
+ }
+
+ @Override
+ public void setDependencies(Object impl) {
+
+ }
}