2 * Copyright (c) 2014 Cisco Systems, Inc. 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.groupbasedpolicy.renderer.ofoverlay.flow;
11 import java.util.HashMap;
14 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
17 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
18 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
24 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
25 import org.slf4j.Logger;
26 import org.slf4j.LoggerFactory;
28 import com.google.common.base.Optional;
31 * Base class for managing flow tables
34 public abstract class FlowTable extends OfTable {
35 protected static final Logger LOG =
36 LoggerFactory.getLogger(FlowTable.class);
38 public FlowTable(OfTableCtx ctx) {
47 public void update(NodeId nodeId, PolicyInfo policyInfo,
48 Dirty dirty) throws Exception {
49 ReadWriteTransaction t = ctx.dataBroker.newReadWriteTransaction();
50 InstanceIdentifier<Table> tiid =
51 FlowUtils.createTablePath(nodeId, getTableId());
53 t.read(LogicalDatastoreType.CONFIGURATION, tiid).get();
55 // Unfortunately, we need to construct a unique string ID for each
56 // flow which is redundant with all the information in the flow itself
57 // We'll build this map so at least we don't have to be O(n^2)
58 HashMap<String, FlowCtx> flowMap = new HashMap<>();
61 Table curTable = (Table)r.get();
63 if (curTable.getFlow() != null) {
64 for (Flow f : curTable.getFlow()) {
65 flowMap.put(f.getId().getValue(), new FlowCtx(f));
70 sync(t, tiid, flowMap, nodeId, policyInfo, dirty);
72 for (FlowCtx fx : flowMap.values()) {
74 t.delete(LogicalDatastoreType.CONFIGURATION,
75 FlowUtils.createFlowPath(tiid, fx.f.getKey()));
80 //ListenableFuture<Void> result = t.submit();
81 //Futures.addCallback(result, updateCallback);
89 * Sync flow state using the flow map
92 public abstract void sync(ReadWriteTransaction t,
93 InstanceIdentifier<Table> tiid,
94 Map<String, FlowCtx> flowMap,
95 NodeId nodeId, PolicyInfo policyInfo,
96 Dirty dirty) throws Exception;
99 * Get the table ID being manipulated
101 public abstract short getTableId();
108 * Get a base flow builder with some common features already set
110 protected FlowBuilder base() {
111 return new FlowBuilder()
112 .setTableId(getTableId())
119 * "Visit" a flow ID by checking if it already exists and if so marking
120 * the {@link FlowCtx} visited bit.
121 * @param flowMap the map containing the existing flows for this table
122 * @param flowId the ID for the flow
123 * @return <code>true</code> if the flow needs to be added
125 protected static boolean visit(Map<String, FlowCtx> flowMap,
127 FlowCtx c = flowMap.get(flowId);
136 * Write the given flow to the transaction
138 protected static void writeFlow(ReadWriteTransaction t,
139 InstanceIdentifier<Table> tiid,
141 LOG.trace("{} {}", flow.getId(), flow);
142 t.put(LogicalDatastoreType.CONFIGURATION,
143 FlowUtils.createFlowPath(tiid, flow.getId()),
148 * Write a drop flow for the given ethertype at the given priority.
149 * If the ethertype is null, then drop all traffic
151 protected void dropFlow(ReadWriteTransaction t,
152 InstanceIdentifier<Table> tiid,
153 Map<String, FlowCtx> flowMap,
154 Integer priority, Long etherType) {
155 FlowId flowid = new FlowId(new StringBuilder()
159 if (visit(flowMap, flowid.getValue())) {
160 FlowBuilder flowb = base()
162 .setPriority(priority)
163 .setInstructions(FlowUtils.dropInstructions());
164 if (etherType != null)
165 flowb.setMatch(new MatchBuilder()
166 .setEthernetMatch(FlowUtils.ethernetMatch(null, null,
169 writeFlow(t, tiid, flowb.build());
174 * Context object for keeping track of flow state
176 protected static class FlowCtx {
178 boolean visited = false;
180 public FlowCtx(Flow f) {