/* * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v1.0 which accompanies this distribution, * and is available at http://www.eclipse.org/legal/epl-v10.html */ package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.mapper.source; import com.google.common.base.Preconditions; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowIdUtils; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils; import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.instruction.go.to.table._case.GoToTable; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId; import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5; import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6; import java.math.BigInteger; import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*; public class SourceMapperFlows { private final NodeId nodeId; private final short tableId; public SourceMapperFlows(NodeId nodeId, short tableId) { this.nodeId = Preconditions.checkNotNull(nodeId); this.tableId = tableId; } /** * Default flow which drops all traffic * * @param priority of flow in the table * @param etherType can be set as specific protocol to match * @param ofWriter flow writer */ void dropFlow(int priority, Long etherType, OfWriter ofWriter) { FlowId flowId; FlowBuilder flowBuilder = FlowUtils.base(tableId) .setPriority(priority) .setInstructions(FlowUtils.dropInstructions()); if (etherType != null) { MatchBuilder matchBuilder = new MatchBuilder() .setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType)); Match match = matchBuilder.build(); flowId = FlowIdUtils.newFlowId(tableId, "drop", match); flowBuilder.setMatch(match); } else { flowId = FlowIdUtils.newFlowId("dropAll"); } flowBuilder.setId(flowId); ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); } /** * Load endpoint ordinals to registers and set tunnel ID value (when exists). Traffic is redirected to destination * mapper * * @param goToTable table ID for {@link GoToTable} instruction * @param priority of the flow * @param ordinals ordinals of the {@link Endpoint} * @param macAddress of the endpoint * @param nodeConnectorId of endpoint openflow port * @param ofWriter flow writer */ public void synchronizeEp(short goToTable, int priority, OrdinalFactory.EndpointFwdCtxOrdinals ordinals, MacAddress macAddress, NodeConnectorId nodeConnectorId, OfWriter ofWriter) { int egId = ordinals.getEpgId(); int bdId = ordinals.getBdId(); int fdId = ordinals.getFdId(); int l3Id = ordinals.getL3Id(); int cgId = ordinals.getCgId(); int tunnelId = ordinals.getTunnelId(); Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId)); Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(cgId)); Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId)); Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId)); Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id)); Action tunIdAction = nxLoadTunIdAction(BigInteger.valueOf(tunnelId), false); Match match = new MatchBuilder().setEthernetMatch(ethernetMatch(macAddress, null, null)) .setInPort(nodeConnectorId) .build(); FlowId flowid = FlowIdUtils.newFlowId(tableId, "ep", match); FlowBuilder flowBuilder = base(tableId).setPriority(priority) .setId(flowid) .setMatch(match) .setInstructions( instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg, tunIdAction), gotoTableIns(goToTable))); ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); } /** * Writes remote tunnel flows. Is evaluated, for which nodes this one acts as a remote node. Then using their * ordinals, tunnel flow is written on this node * * @param goToTable table ID for {@link GoToTable} instruction * @param priority of the flow * @param tunnel port number * @param remoteOrdinals ordinals of remote node * @param ofWriter flow writer */ public void createTunnelFlow(short goToTable, int priority, NodeConnectorId tunnel, OrdinalFactory.EndpointFwdCtxOrdinals remoteOrdinals, OfWriter ofWriter) { int egId = remoteOrdinals.getEpgId(); int bdId = remoteOrdinals.getBdId(); int fdId = remoteOrdinals.getFdId(); int l3Id = remoteOrdinals.getL3Id(); int tunnelId = remoteOrdinals.getTunnelId(); MatchBuilder matchBuilder = new MatchBuilder().setInPort(tunnel); addNxTunIdMatch(matchBuilder, tunnelId); Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId)); Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0xffffff)); Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId)); Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId)); Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id)); Match match = matchBuilder.build(); FlowId flowId = FlowIdUtils.newFlowId(tableId, "tunnel", match); FlowBuilder flowBuilder = base(tableId).setId(flowId) .setPriority(priority) .setMatch(match) .setInstructions( instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg), gotoTableIns(goToTable))); ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); } /** * Writes remote broadcast flows. Is evaluated, for which nodes this one acts as a remote node. Then using their * ordinals, broadcast flow is written on this node * * @param goToTable table ID for {@link GoToTable} instruction * @param priority of the flow * @param tunnel port number * @param remoteOrdinals ordinals of remote node * @param ofWriter flow writer */ public void createBroadcastFlow(short goToTable, int priority, NodeConnectorId tunnel, OrdinalFactory.EndpointFwdCtxOrdinals remoteOrdinals, OfWriter ofWriter) { int fdId = remoteOrdinals.getFdId(); MatchBuilder matchBuilder = new MatchBuilder().setInPort(tunnel); addNxTunIdMatch(matchBuilder, fdId); Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId)); Match match = matchBuilder.build(); FlowId flowId = FlowIdUtils.newFlowId(tableId, "tunnelFdId", match); FlowBuilder flowBuilder = base(tableId).setId(flowId) .setPriority(priority) .setMatch(match) .setInstructions(instructions(applyActionIns(fdReg), gotoTableIns(goToTable))); ofWriter.writeFlow(nodeId, tableId, flowBuilder.build()); } }