cbb554ca0a18e238ebc19d26870d3b8dbcb0c220
[groupbasedpolicy.git] / renderers / ofoverlay / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ofoverlay / flow / SourceMapper.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow;
10
11 import java.math.BigInteger;
12 import java.util.List;
13 import java.util.Map;
14
15 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
16 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
17 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.Dirty;
18 import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
19 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
20 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
21 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.Table;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg4;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg6;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
45
46 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.*;
47
48 /**
49  * Manage the table that assigns source endpoint group, bridge domain, and 
50  * router domain to registers to be used by other tables.
51  * @author readams
52  */
53 public class SourceMapper extends FlowTable {
54     protected static final Logger LOG =
55             LoggerFactory.getLogger(SourceMapper.class);
56
57     public static final short TABLE_ID = 1;
58
59     public SourceMapper(OfContext ctx) {
60         super(ctx);
61     }
62
63     @Override
64     public short getTableId() {
65         return TABLE_ID;
66     }
67
68     @Override
69     public void sync(ReadWriteTransaction t,
70                      InstanceIdentifier<Table> tiid,
71                      Map<String, FlowCtx> flowMap, 
72                      NodeId nodeId, PolicyInfo policyInfo, 
73                      Dirty dirty) throws Exception {
74         dropFlow(t, tiid, flowMap, Integer.valueOf(1), null);
75
76         for (EgKey sepg : ctx.getEndpointManager().getGroupsForNode(nodeId)) {
77             IndexedTenant tenant = 
78                     ctx.getPolicyResolver().getTenant(sepg.getTenantId());
79             if (tenant == null) continue;
80
81             EndpointGroup eg = tenant.getEndpointGroup(sepg.getEgId());
82             L3Context l3c = tenant.resolveL3Context(eg.getNetworkDomain());
83             L2BridgeDomain bd = tenant.resolveL2BridgeDomain(eg.getNetworkDomain());
84             L2FloodDomain fd = tenant.resolveL2FloodDomain(eg.getNetworkDomain());
85             int egId = 0, bdId = 0, fdId = 0, l3Id = 0;
86             
87             egId = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
88                                                        sepg.getEgId());
89             if (bd != null)
90                 bdId = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
91                                                            bd.getId());
92             if (fd != null)
93                 fdId = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
94                                                            fd.getId());
95             if (l3c != null)
96                 l3Id = ctx.getPolicyManager().getContextOrdinal(sepg.getTenantId(),
97                                                            l3c.getId());
98
99             NodeConnectorId tunPort =
100                     ctx.getSwitchManager().getTunnelPort(nodeId);
101             if (tunPort != null) {
102                 FlowId flowid = new FlowId(new StringBuilder()
103                     .append(tunPort.getValue())
104                     .append("|tunnel|")
105                     .append(egId)
106                     .append("|")
107                     .append(bdId)
108                     .append("|")
109                     .append(fdId)
110                     .append("|")
111                     .append(l3Id)
112                     .toString());
113                 if (visit(flowMap, flowid.getValue())) {
114                     MatchBuilder mb = new MatchBuilder()
115                         .setInPort(tunPort);
116                     addNxTunIdMatch(mb, egId);
117                     Action segReg = nxLoadRegAction(NxmNxReg0.class, 
118                                                     BigInteger.valueOf(egId));
119                     // set condition group register to all ones to bypass
120                     // policy enforcement
121                     Action scgReg = nxLoadRegAction(NxmNxReg1.class,
122                                                     BigInteger.valueOf(0xffffff));
123                     Action bdReg = nxLoadRegAction(NxmNxReg4.class, 
124                                                    BigInteger.valueOf(bdId));
125                     Action fdReg = nxLoadRegAction(NxmNxReg5.class, 
126                                                    BigInteger.valueOf(fdId));
127                     Action vrfReg = nxLoadRegAction(NxmNxReg6.class, 
128                                                     BigInteger.valueOf(l3Id));
129                     FlowBuilder flowb = base()
130                         .setId(flowid)
131                         .setPriority(Integer.valueOf(150))
132                         .setMatch(mb.build())
133                         .setInstructions(instructions(applyActionIns(segReg,
134                                                                      scgReg,
135                                                                      bdReg,
136                                                                      fdReg,
137                                                                      vrfReg),
138                                                       gotoTableIns((short)(TABLE_ID + 1))));
139                     writeFlow(t, tiid, flowb.build());
140                 }
141             }
142             
143             for (Endpoint e : ctx.getEndpointManager().getEPsForNode(nodeId, sepg)) {
144                 OfOverlayContext ofc = e.getAugmentation(OfOverlayContext.class);
145                 if (ofc != null && ofc.getNodeConnectorId() != null &&
146                         (ofc.getLocationType() == null ||
147                         LocationType.Internal.equals(ofc.getLocationType())) &&
148                         e.getTenant() != null && e.getEndpointGroup() != null) {
149                     syncEP(t, tiid, flowMap, policyInfo, nodeId, e, ofc,
150                            egId, bdId, fdId, l3Id);
151                 } 
152             }
153         }
154     }
155     
156     private void syncEP(ReadWriteTransaction t,
157                         InstanceIdentifier<Table> tiid,
158                         Map<String, FlowCtx> flowMap, 
159                         PolicyInfo policyInfo,
160                         NodeId nodeId, Endpoint e, OfOverlayContext ofc,
161                         int egId, int bdId, int fdId, int l3Id) 
162                                  throws Exception {
163         // Set sEPG, flood domain, bridge domain, and layer 3 context 
164         // for internal endpoints by directly matching each endpoint
165
166         List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(e);
167         ConditionGroup cg = 
168                 policyInfo.getEgCondGroup(new EgKey(e.getTenant(), 
169                                                     e.getEndpointGroup()), 
170                                           conds);
171         int cgId = ctx.getPolicyManager().getCondGroupOrdinal(cg);
172
173         FlowId flowid = new FlowId(new StringBuilder()
174             .append(ofc.getNodeConnectorId().getValue())
175             .append("|")
176             .append(e.getMacAddress().getValue())
177             .append("|")
178             .append(egId)
179             .append("|")
180             .append(bdId)
181             .append("|")
182             .append(fdId)
183             .append("|")
184             .append(l3Id)
185             .append("|")
186             .append(cgId)
187             .toString());
188         if (visit(flowMap, flowid.getValue())) {
189             Action segReg = nxLoadRegAction(NxmNxReg0.class, 
190                                             BigInteger.valueOf(egId));
191             Action scgReg = nxLoadRegAction(NxmNxReg1.class, 
192                                             BigInteger.valueOf(cgId));
193             Action bdReg = nxLoadRegAction(NxmNxReg4.class, 
194                                            BigInteger.valueOf(bdId));
195             Action fdReg = nxLoadRegAction(NxmNxReg5.class, 
196                                            BigInteger.valueOf(fdId));
197             Action vrfReg = nxLoadRegAction(NxmNxReg6.class, 
198                                             BigInteger.valueOf(l3Id));
199             FlowBuilder flowb = base()
200                 .setPriority(Integer.valueOf(100))
201                 .setId(flowid)
202                 .setMatch(new MatchBuilder()
203                     .setEthernetMatch(ethernetMatch(e.getMacAddress(), 
204                                                     null, null))
205                     .setInPort(ofc.getNodeConnectorId())
206                     .build())
207                 .setInstructions(instructions(applyActionIns(segReg,
208                                                              scgReg,
209                                                              bdReg,
210                                                              fdReg,
211                                                              vrfReg),
212                                               gotoTableIns((short)(TABLE_ID + 1))));
213             writeFlow(t, tiid, flowb.build());
214         }
215     }
216 }