1 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
3 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxNsiMatch;
4 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxNspMatch;
5 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxRegMatch;
6 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxTunIdMatch;
7 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
8 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
9 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
10 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;
11 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIPv4Action;
12 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction;
13 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
14 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadNshc1RegAction;
15 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadNshc2RegAction;
16 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.outputAction;
17 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxTunIpv4DstMatch;
19 import java.math.BigInteger;
20 import java.util.List;
22 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
23 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
24 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
25 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
26 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.PolicyEnforcer.NetworkElements;
27 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ChainAction;
28 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sfcutils.SfcNshHeader;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlanGpe;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 public class ChainActionFlows {
51 private static final Logger LOG = LoggerFactory.getLogger(ChainAction.class);
53 public ChainActionFlows() {
57 public static void createChainTunnelFlows(SfcNshHeader sfcNshHeader, NetworkElements netElements, FlowMap flowMap,
60 NodeId localNodeId = netElements.getLocalNodeId();
61 NodeId destNodeId = netElements.getDstEp().getAugmentation(OfOverlayContext.class).getNodeId();
62 NodeConnectorId localNodeTunPort = ctx.getSwitchManager().getTunnelPort(localNodeId, TunnelTypeVxlanGpe.class);
63 NodeConnectorId destNodeTunPort = ctx.getSwitchManager().getTunnelPort(destNodeId, TunnelTypeVxlanGpe.class);
64 if (localNodeTunPort == null || destNodeTunPort == null) {
65 LOG.error("createChainTunnelFlows: No valid VXLAN GPE tunnel for Node {} or Node {}", localNodeId,
69 flowMap.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_PORTSECURITY(),
70 allowFromChainPort(localNodeTunPort, ctx.getPolicyManager().getTABLEID_PORTSECURITY(), ctx));
72 flowMap.writeFlow(localNodeId, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER(),
73 allowFromChainTunnel(localNodeTunPort, ctx.getPolicyManager().getTABLEID_POLICY_ENFORCER()));
77 ctx.getPolicyManager().getTABLEID_EXTERNAL_MAPPER(),
78 createExternalFlow(sfcNshHeader, localNodeTunPort, netElements, ctx.getPolicyManager()
79 .getTABLEID_EXTERNAL_MAPPER(), ctx));
83 ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(),
84 createChainTunnelFlow(sfcNshHeader, destNodeTunPort, netElements.getSrcEpOrds(), ctx.getPolicyManager()
85 .getTABLEID_SOURCE_MAPPER(), ctx));
89 ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(),
90 createChainBroadcastFlow(sfcNshHeader, destNodeTunPort, netElements.getSrcEpOrds(),
91 ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER(), ctx));
95 private static Flow createChainBroadcastFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort,
96 EndpointFwdCtxOrdinals epFwdCtxOrds, short tableId, OfContext ctx) {
98 int fdId = epFwdCtxOrds.getFdId();
100 MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
102 addNxNsiMatch(mb, sfcNshHeader.getNshNsiFromChain());
103 addNxNspMatch(mb, sfcNshHeader.getNshNspFromChain());
104 addNxTunIdMatch(mb, fdId);
106 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action fdReg = nxLoadRegAction(
107 NxmNxReg5.class, BigInteger.valueOf(fdId));
109 Match match = mb.build();
110 FlowId flowId = FlowIdUtils.newFlowId(tableId, "chainbroadcast", match);
112 FlowBuilder flowb = base(tableId).setId(flowId)
113 .setPriority(Integer.valueOf(150))
116 instructions(applyActionIns(fdReg), gotoTableIns(ctx.getPolicyManager()
117 .getTABLEID_DESTINATION_MAPPER())));
118 return flowb.build();
121 private static Flow createExternalFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort,
122 NetworkElements netElements, short tableId, OfContext ctx) {
124 Integer priority = 1000;
126 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadC1 = nxLoadNshc1RegAction(sfcNshHeader.getNshMetaC1());
127 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadC2 = nxLoadNshc2RegAction(sfcNshHeader.getNshMetaC2());
128 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunVnid =
129 nxLoadTunIdAction(BigInteger.valueOf(netElements.getSrcEpOrds().getTunnelId()), false);
130 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action loadChainTunDest = nxLoadTunIPv4Action(sfcNshHeader.getNshTunIpDst().getValue(), false);
133 MatchBuilder mb = new MatchBuilder();
134 addNxRegMatch(mb, RegMatch.of(NxmNxReg6.class, Long.valueOf(netElements.getDstEpOrds().getL3Id())));
135 addNxTunIdMatch(mb, netElements.getSrcEpOrds().getTunnelId());
136 addNxNspMatch(mb, sfcNshHeader.getNshNspToChain());
137 addNxNsiMatch(mb, sfcNshHeader.getNshNsiToChain());
138 if (!netElements.getDstEp().getAugmentation(OfOverlayContext.class).getNodeId().equals(netElements.getLocalNodeId())) {
139 addNxTunIpv4DstMatch(mb, ctx.getSwitchManager().getTunnelIP(netElements.getDstNodeId(), TunnelTypeVxlan.class).getIpv4Address());
143 Match match = mb.build();
144 FlowId flowId = FlowIdUtils.newFlowId(tableId, "chainexternal", match);
145 FlowBuilder flowb = base(tableId).setId(flowId)
146 .setPriority(Integer.valueOf(priority))
148 .setInstructions(instructions(applyActionIns(loadC1, loadC2, loadChainTunDest, loadChainTunVnid, outputAction(tunPort))));
149 return flowb.build();
152 private static Flow createChainTunnelFlow(SfcNshHeader sfcNshHeader, NodeConnectorId tunPort,
153 EndpointFwdCtxOrdinals epFwdCtxOrds, short tableId, OfContext ctx) {
155 int egId = epFwdCtxOrds.getEpgId();
156 int bdId = epFwdCtxOrds.getBdId();
157 int fdId = epFwdCtxOrds.getFdId();
158 int l3Id = epFwdCtxOrds.getL3Id();
159 int tunnelId = epFwdCtxOrds.getTunnelId();
161 MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
162 addNxTunIdMatch(mb, tunnelId);
163 addNxNspMatch(mb, sfcNshHeader.getNshNspFromChain());
164 addNxNsiMatch(mb, sfcNshHeader.getNshNsiFromChain());
166 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action segReg = nxLoadRegAction(
167 NxmNxReg0.class, BigInteger.valueOf(egId));
168 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action scgReg = nxLoadRegAction(
169 NxmNxReg1.class, BigInteger.valueOf(0xffffff));
170 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action bdReg = nxLoadRegAction(
171 NxmNxReg4.class, BigInteger.valueOf(bdId));
172 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action fdReg = nxLoadRegAction(
173 NxmNxReg5.class, BigInteger.valueOf(fdId));
174 org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action vrfReg = nxLoadRegAction(
175 NxmNxReg6.class, BigInteger.valueOf(l3Id));
177 Match match = mb.build();
178 FlowId flowId = FlowIdUtils.newFlowId(tableId, "chaintunnel", match);
179 FlowBuilder flowb = base(tableId).setId(flowId)
180 .setPriority(Integer.valueOf(150))
183 instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),
184 gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
185 return flowb.build();
188 private static Flow allowFromChainPort(NodeConnectorId port, short tableId, OfContext ctx) {
190 Match match = new MatchBuilder().setInPort(port).build();
191 FlowId flowId = FlowIdUtils.newFlowId(tableId, "chainport", match);
192 FlowBuilder flowb = base(tableId).setId(flowId)
193 .setPriority(Integer.valueOf(200))
195 .setInstructions(FlowUtils.gotoTableInstructions(ctx.getPolicyManager().getTABLEID_SOURCE_MAPPER()));
196 return flowb.build();
199 private static Flow allowFromChainTunnel(NodeConnectorId tunPort, short tableId) {
201 MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
202 addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
203 Match match = mb.build();
204 FlowId flowId = FlowIdUtils.newFlowId(tableId, "chainport", match);
206 FlowBuilder flow = base(tableId).setId(flowId)
209 .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
215 * Get a base flow builder with some common features already set
217 private static FlowBuilder base(short tableId) {
218 return new FlowBuilder().setTableId(tableId).setBarrier(false).setHardTimeout(0).setIdleTimeout(0);