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 static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.addNxTunIdMatch;
12 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
13 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.ethernetMatch;
14 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.gotoTableIns;
15 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
16 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadRegAction;
17 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxLoadTunIdAction;
19 import java.math.BigInteger;
20 import java.util.Collections;
21 import java.util.HashSet;
24 import org.opendaylight.groupbasedpolicy.dto.EgKey;
25 import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;
26 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
27 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfWriter;
28 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.endpoint.EndpointManager;
29 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 import com.google.common.collect.Sets;
53 * Manage the table that assigns source endpoint group, bridge domain, and
54 * router domain to registers to be used by other tables.
56 public class SourceMapper extends FlowTable {
58 protected static final Logger LOG = LoggerFactory.getLogger(SourceMapper.class);
60 // TODO Li alagalah Improve UT coverage for this class.
61 public static short TABLE_ID;
63 public SourceMapper(OfContext ctx, short tableId) {
69 public short getTableId() {
74 public void sync(NodeId nodeId, OfWriter ofWriter) throws Exception {
76 ofWriter.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
78 // Handle case where packets from from External
79 for (Endpoint ep : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
80 IndexedTenant tenant = ctx.getTenant(ep.getTenant());
84 EndpointFwdCtxOrdinals epFwdCtxOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, ep);
85 if (epFwdCtxOrds == null) {
86 LOG.debug("getEndpointFwdCtxOrdinals is null for EP {}", ep);
90 createRemoteTunnels(ofWriter, nodeId, ep, epFwdCtxOrds);
92 if (ep.getTenant() == null || (ep.getEndpointGroup() == null && ep.getEndpointGroups() == null)) {
96 OfOverlayContext ofc = ep.getAugmentation(OfOverlayContext.class);
97 if (ofc != null && ofc.getNodeConnectorId() != null
98 && (EndpointManager.isInternal(ep, ctx.getTenant(ep.getTenant()).getExternalImplicitGroups()))) {
100 * Sync the local EP information.
102 syncEP(ofWriter, nodeId, ep, ofc.getNodeConnectorId(), epFwdCtxOrds);
107 private void createRemoteTunnels(OfWriter ofWriter, NodeId nodeId, Endpoint ep, EndpointFwdCtxOrdinals epFwdCtxOrds)
109 Set<EgKey> epgs = new HashSet<>();
111 // Get EPGs and add to Set to remove duplicates
112 // TODO alagalah Li: test EndpointManager.getEgKeys
113 if (ep.getEndpointGroup() != null) {
114 epgs.add(new EgKey(ep.getTenant(), ep.getEndpointGroup()));
116 if (ep.getEndpointGroups() != null) {
117 for (EndpointGroupId epgId : ep.getEndpointGroups()) {
118 epgs.add(new EgKey(ep.getTenant(), epgId));
122 // Create tunnels on remote Nodes that may talk to us.
123 for (EgKey epg : epgs) {
124 Set<EgKey> peers = Sets.union(Collections.singleton(epg), ctx.getCurrentPolicy().getPeers(epg));
125 for (EgKey peer : peers) {
126 for (NodeId remoteNodeId : ctx.getEndpointManager().getNodesForGroup(peer)) {
128 // Please do not check for remote v local nodeID, we need local to local tunnels
129 // in the case of chaining - The Great Dr Sunal.
130 NodeConnectorId tunPort = ctx.getSwitchManager().getTunnelPort(remoteNodeId, TunnelTypeVxlan.class);
131 if (tunPort == null) {
132 LOG.trace("No tunnel port for tunnel in SourceMapper between local:{} and remote:{}",
133 nodeId.getValue(), remoteNodeId.getValue());
136 ofWriter.writeFlow(remoteNodeId, TABLE_ID, createTunnelFlow(tunPort, epFwdCtxOrds));
137 ofWriter.writeFlow(remoteNodeId, TABLE_ID, createBroadcastFlow(tunPort, epFwdCtxOrds));
143 private Flow createBroadcastFlow(NodeConnectorId tunPort, EndpointFwdCtxOrdinals epFwdCtxOrds) {
145 int fdId = epFwdCtxOrds.getFdId();
147 MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
148 addNxTunIdMatch(mb, fdId);
150 // set condition group register to all ones to
152 // policy enforcement
154 * TODO: This breaks distributed policy enforcement
155 * especially wrt multi-action. BAD. Must be addressed
156 * (this is why we can't have nice things).
157 * This can be fixed with new tunnelId ordinal in
161 Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
163 Match match = mb.build();
164 FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "tunnelFdId", match);
165 FlowBuilder flowb = base().setId(flowid)
166 .setPriority(Integer.valueOf(150))
168 .setInstructions(instructions(applyActionIns(fdReg), gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
169 return flowb.build();
172 private Flow createTunnelFlow(NodeConnectorId tunPort, EndpointFwdCtxOrdinals epFwdCtxOrds) {
173 // ... this is a remote node.
175 int egId = epFwdCtxOrds.getEpgId();
176 int bdId = epFwdCtxOrds.getBdId();
177 int fdId = epFwdCtxOrds.getFdId();
178 int l3Id = epFwdCtxOrds.getL3Id();
179 int tunnelId = epFwdCtxOrds.getTunnelId();
181 MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
182 addNxTunIdMatch(mb, tunnelId);
184 Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId));
185 // set condition group register to all ones to
187 // policy enforcement
189 * TODO: This breaks distributed policy enforcement
190 * especially wrt multi-action. BAD. Must be addressed
191 * (this is why we can't have nice things).
192 * This can be fixed with new tunnelId ordinal in
195 Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(0xffffff));
196 Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId));
197 Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
198 Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id));
199 Match match = mb.build();
200 FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "tunnel", match);
201 FlowBuilder flowb = base().setId(flowid)
202 .setPriority(Integer.valueOf(150))
205 instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg),
206 gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
207 return flowb.build();
210 private void syncEP(OfWriter ofWriter, NodeId nodeId, Endpoint ep, NodeConnectorId ncId, EndpointFwdCtxOrdinals epFwdCtxOrds) throws Exception {
212 // TODO alagalah Li/Be: We should also match on EndpointL3 with the appropriate
213 // network containment. This would solve a lot of problems and prepare for EndpointL3 RPC.
215 int egId = epFwdCtxOrds.getEpgId();
216 int bdId = epFwdCtxOrds.getBdId();
217 int fdId = epFwdCtxOrds.getFdId();
218 int l3Id = epFwdCtxOrds.getL3Id();
219 int cgId = epFwdCtxOrds.getCgId();
220 int tunnelId = epFwdCtxOrds.getTunnelId();
222 Action segReg = nxLoadRegAction(NxmNxReg0.class, BigInteger.valueOf(egId));
223 Action scgReg = nxLoadRegAction(NxmNxReg1.class, BigInteger.valueOf(cgId));
224 Action bdReg = nxLoadRegAction(NxmNxReg4.class, BigInteger.valueOf(bdId));
225 Action fdReg = nxLoadRegAction(NxmNxReg5.class, BigInteger.valueOf(fdId));
226 Action vrfReg = nxLoadRegAction(NxmNxReg6.class, BigInteger.valueOf(l3Id));
227 Action tunIdAction = nxLoadTunIdAction(BigInteger.valueOf(tunnelId), false);
229 Match match = new MatchBuilder().setEthernetMatch(ethernetMatch(ep.getMacAddress(), null, null))
232 FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "ep", match);
233 FlowBuilder flowb = base().setPriority(Integer.valueOf(100))
237 instructions(applyActionIns(segReg, scgReg, bdReg, fdReg, vrfReg,tunIdAction),
238 gotoTableIns(ctx.getPolicyManager().getTABLEID_DESTINATION_MAPPER())));
239 ofWriter.writeFlow(nodeId, TABLE_ID, flowb.build());