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.addNxRegMatch;
12 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.writeActionIns;
13 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.applyActionIns;
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.nxOutputRegAction;
17 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.EndpointManager.isExternal;
19 import java.util.ArrayList;
20 import java.util.Collection;
21 import java.util.Collections;
22 import java.util.Comparator;
23 import java.util.HashMap;
24 import java.util.HashSet;
25 import java.util.List;
29 import javax.annotation.concurrent.Immutable;
31 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
32 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
33 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
34 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
35 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
36 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action;
37 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
38 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassificationResult;
39 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Classifier;
40 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ParamDerivator;
41 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures;
42 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
43 import org.opendaylight.groupbasedpolicy.resolver.EndpointConstraint;
44 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
45 import org.opendaylight.groupbasedpolicy.resolver.Policy;
46 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
47 import org.opendaylight.groupbasedpolicy.resolver.RuleGroup;
48 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.Instruction;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.list.InstructionBuilder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.EndpointLocation.LocationType;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.ofoverlay.rev140528.OfOverlayContext;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstance;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
84 import org.slf4j.Logger;
85 import org.slf4j.LoggerFactory;
87 import com.google.common.collect.ComparisonChain;
88 import com.google.common.collect.Ordering;
89 import com.google.common.collect.Table.Cell;
92 * Manage the table that enforces policy on the traffic. Traffic is denied
93 * unless specifically allowed by policy
95 public class PolicyEnforcer extends FlowTable {
97 protected static final Logger LOG = LoggerFactory.getLogger(PolicyEnforcer.class);
99 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction gotoEgressNatInstruction;
100 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction gotoExternalInstruction;
102 public static short TABLE_ID;
104 public PolicyEnforcer(OfContext ctx, short tableId) {
106 this.TABLE_ID=tableId;
107 this.gotoEgressNatInstruction = gotoTableIns(ctx.getPolicyManager().getTABLEID_EGRESS_NAT());
108 this.gotoExternalInstruction = gotoTableIns(ctx.getPolicyManager().getTABLEID_EGRESS_NAT());
116 public short getTableId() {
121 public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
123 flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null, TABLE_ID));
125 NodeConnectorId tunPort = SwitchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class);
126 if (tunPort != null) {
127 flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(tunPort));
130 HashSet<CgPair> visitedPairs = new HashSet<>();
132 // Used for ARP flows
133 Set<Integer> fdIds = new HashSet<>();
135 for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
136 for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
137 Set<EgKey> peers = policyInfo.getPeers(srcEpgKey);
138 for (EgKey dstEpgKey : peers) {
139 Set<Endpoint> dstEndpoints = new HashSet<>();
140 dstEndpoints.addAll(ctx.getEndpointManager().getEndpointsForGroup(dstEpgKey));
141 dstEndpoints.addAll(ctx.getEndpointManager().getExtEpsNoLocForGroup(dstEpgKey));
142 for (Endpoint dstEp : dstEndpoints) {
144 EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
146 EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
148 int dcgId = dstEpFwdCxtOrds.getCgId();
149 int depgId = dstEpFwdCxtOrds.getEpgId();
150 int scgId = srcEpFwdCxtOrds.getCgId();
151 int sepgId = srcEpFwdCxtOrds.getEpgId();
152 NetworkElements netElements = new NetworkElements(srcEp, dstEp, nodeId, ctx, policyInfo);
153 fdIds.add(srcEpFwdCxtOrds.getFdId());
155 Policy policy = policyInfo.getPolicy(dstEpgKey, srcEpgKey);
156 for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints: getActiveRulesBetweenEps(policy, dstEp, srcEp)) {
157 Set<IpPrefix> sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey()
159 Set<IpPrefix> dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey()
161 CgPair p = new CgPair(depgId, sepgId, dcgId, scgId, dIpPrefixes, sIpPrefixes);
162 if (visitedPairs.contains(p))
165 syncPolicy(flowMap, netElements, activeRulesByConstraints.getValue(), p);
169 policy = policyInfo.getPolicy(srcEpgKey, dstEpgKey);
170 for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints : getActiveRulesBetweenEps(policy, srcEp, dstEp)) {
171 Set<IpPrefix> sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey()
173 Set<IpPrefix> dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey()
175 CgPair p = new CgPair(sepgId, depgId, scgId, dcgId, sIpPrefixes, dIpPrefixes);
176 if (visitedPairs.contains(p))
179 syncPolicy(flowMap, netElements, activeRulesByConstraints.getValue(), p);
187 // Set<Endpoint> visitedEps = new HashSet<>();
188 for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
189 // visitedEps.add(srcEp);
190 for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
192 IndexedTenant tenant = ctx.getPolicyResolver().getTenant(srcEpgKey.getTenantId());
193 EndpointGroup group = tenant.getEndpointGroup(srcEpgKey.getEgId());
194 IntraGroupPolicy igp = group.getIntraGroupPolicy();
196 if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
197 for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(srcEpgKey)) {
199 // if(visitedEps.contains(dstEp)) {
202 // visitedEps.add(dstEp);
203 EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
205 EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
207 int depgId = dstEpFwdCxtOrds.getEpgId();
208 int sepgId = srcEpFwdCxtOrds.getEpgId();
209 flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(sepgId, depgId));
210 flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(depgId, sepgId));
216 // Write ARP flows per flood domain.
217 for (Integer fdId : fdIds) {
218 flowMap.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
222 private Flow createArpFlow(Integer fdId) {
224 Long etherType = FlowUtils.ARP;
225 // L2 Classifier so 20,000 for now
226 Integer priority = 20000;
228 MatchBuilder mb = new MatchBuilder().setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType));
230 addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(fdId)));
232 Match match = mb.build();
233 FlowId flowid = FlowIdUtils.newFlowId(TABLE_ID, "arp", match);
234 Flow flow = base().setPriority(priority)
237 .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))))
242 private Flow allowSameEpg(int sepgId, int depgId) {
244 MatchBuilder mb = new MatchBuilder();
245 addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, Long.valueOf(sepgId)),
246 RegMatch.of(NxmNxReg2.class, Long.valueOf(depgId)));
247 Match match = mb.build();
248 FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "intraallow", match);
249 FlowBuilder flow = base().setId(flowId)
252 .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
256 private Flow allowFromTunnel(NodeConnectorId tunPort) {
258 MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
259 addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
260 Match match = mb.build();
261 FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "tunnelallow", match);
262 FlowBuilder flow = base().setId(flowId)
265 .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
270 private void syncPolicy(FlowMap flowMap, NetworkElements netElements, List<RuleGroup> rgs, CgPair p) {
271 int priority = 65000;
272 for (RuleGroup rg : rgs) {
273 TenantId tenantId = rg.getContractTenant().getId();
274 IndexedTenant tenant = ctx.getPolicyResolver().getTenant(tenantId);
275 for (Rule r : rg.getRules()) {
276 syncDirection(flowMap, netElements, tenant, p, r, Direction.In, priority);
277 syncDirection(flowMap, netElements, tenant, p, r, Direction.Out, priority);
285 * Private internal class for ordering Actions in Rules. The order is
286 * determined first by the value of the order parameter, with the lower
287 * order actions being applied first; for Actions with either the same order
288 * or no order, ordering is lexicographical by name.
290 private static class ActionRefComparator implements Comparator<ActionRef> {
292 public static final ActionRefComparator INSTANCE = new ActionRefComparator();
295 public int compare(ActionRef arg0, ActionRef arg1) {
296 return ComparisonChain.start()
297 .compare(arg0.getOrder(), arg1.getOrder(), Ordering.natural().nullsLast())
298 .compare(arg0.getName().getValue(), arg1.getName().getValue(), Ordering.natural().nullsLast())
304 private void syncDirection(FlowMap flowMap, NetworkElements netElements, IndexedTenant contractTenant, CgPair cgPair, Rule rule,
305 Direction direction, int priority) {
307 * Create the ordered action list. The implicit action is "allow", and
308 * is therefore always in the list
310 * TODO: revisit implicit vs. default for "allow" TODO: look into
311 * incorporating operational policy for actions
314 // TODO: can pass Comparator ActionRefComparator to List constructor, rather than
315 // referencing in sort
316 List<ActionBuilder> actionBuilderList = new ArrayList<ActionBuilder>();
317 if (rule.getActionRef() != null) {
319 * Pre-sort by references using order, then name
321 List<ActionRef> actionRefList = new ArrayList<ActionRef>(rule.getActionRef());
322 Collections.sort(actionRefList, ActionRefComparator.INSTANCE);
324 for (ActionRef actionRule : actionRefList) {
325 ActionInstance actionInstance = contractTenant.getAction(actionRule.getName());
326 if (actionInstance == null) {
327 // XXX TODO fail the match and raise an exception
328 LOG.warn("Action instance {} not found", actionRule.getName().getValue());
331 Action action = SubjectFeatures.getAction(actionInstance.getActionDefinitionId());
332 if (action == null) {
333 // XXX TODO fail the match and raise an exception
334 LOG.warn("Action definition {} not found", actionInstance.getActionDefinitionId().getValue());
338 Map<String, Object> params = new HashMap<>();
339 if (actionInstance.getParameterValue() != null) {
340 for (ParameterValue v : actionInstance.getParameterValue()) {
341 if (v.getName() == null)
343 if (v.getIntValue() != null) {
344 params.put(v.getName().getValue(), v.getIntValue());
345 } else if (v.getStringValue() != null) {
346 params.put(v.getName().getValue(), v.getStringValue());
351 * Convert the GBP Action to one or more OpenFlow Actions
353 actionBuilderList = action.updateAction(actionBuilderList, params, actionRule.getOrder(),netElements);
356 Action act = SubjectFeatures.getAction(AllowAction.DEFINITION.getId());
357 actionBuilderList = act.updateAction(actionBuilderList, new HashMap<String, Object>(), 0, netElements);
360 Map<String, ParameterValue> paramsFromClassifier = new HashMap<>();
361 Set<ClassifierDefinitionId> classifiers = new HashSet<>();
362 for (ClassifierRef cr : rule.getClassifierRef()) {
363 if (cr.getDirection() != null && !cr.getDirection().equals(Direction.Bidirectional)
364 && !cr.getDirection().equals(direction)) {
368 // XXX - TODO - implement connection tracking (requires openflow
369 // extension and data plane support - in 2.4. Will need to handle
370 // case where we are working with mix of nodes.
372 ClassifierInstance ci = contractTenant.getClassifier(cr.getName());
374 // XXX TODO fail the match and raise an exception
375 LOG.warn("Classifier instance {} not found", cr.getName().getValue());
378 Classifier cfier = SubjectFeatures.getClassifier(ci.getClassifierDefinitionId());
380 // XXX TODO fail the match and raise an exception
381 LOG.warn("Classifier definition {} not found", ci.getClassifierDefinitionId().getValue());
384 classifiers.add(new ClassifierDefinitionId(ci.getClassifierDefinitionId()));
385 for (ParameterValue v : ci.getParameterValue()) {
386 if (paramsFromClassifier.get(v.getName().getValue()) == null) {
387 if (v.getIntValue() != null
388 || v.getStringValue() != null
389 || v.getRangeValue() != null) {
390 paramsFromClassifier.put(v.getName().getValue(), v);
393 if (!paramsFromClassifier.get(v.getName().getValue()).equals(v)) {
394 throw new IllegalArgumentException("Classification error in rule: " + rule.getName()
395 + ".\nCause: " + "Classification conflict detected at parameter " + v.getName());
400 if(classifiers.isEmpty()) {
403 List<Map<String, ParameterValue>> derivedParamsByName = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(paramsFromClassifier);
404 String baseId = createBaseFlowId(direction, cgPair, priority);
405 List<MatchBuilder> flowMatchBuilders = new ArrayList<>();
406 for (Map<String, ParameterValue> params : derivedParamsByName) {
407 List<MatchBuilder> matchBuildersToResolve = new ArrayList<>();
408 if (cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
409 matchBuildersToResolve.add(createBaseMatch(direction, cgPair, null, null));
410 } else if (!cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
411 for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
412 matchBuildersToResolve.add(createBaseMatch(direction, cgPair, sIpPrefix, null));
414 } else if (cgPair.sIpPrefixes.isEmpty() && !cgPair.dIpPrefixes.isEmpty()) {
415 for (IpPrefix dIpPrefix : cgPair.sIpPrefixes) {
416 matchBuildersToResolve.add(createBaseMatch(direction, cgPair, null, dIpPrefix));
419 for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
420 for (IpPrefix dIpPrefix : cgPair.sIpPrefixes) {
421 matchBuildersToResolve.add(createBaseMatch(direction, cgPair, sIpPrefix, dIpPrefix));
425 for (ClassifierDefinitionId clDefId : classifiers) {
426 Classifier classifier = SubjectFeatures.getClassifier(clDefId);
427 ClassificationResult result = classifier.updateMatch(matchBuildersToResolve, params);
428 if (!result.isSuccessfull()) {
429 // TODO consider different handling.
430 throw new IllegalArgumentException("Classification conflict detected in rule: " + rule.getName() + ".\nCause: "
431 + result.getErrorMessage());
433 matchBuildersToResolve = new ArrayList<>(result.getMatchBuilders());
435 flowMatchBuilders.addAll(matchBuildersToResolve);
438 FlowBuilder flow = base().setPriority(Integer.valueOf(priority));
439 for (MatchBuilder mb : flowMatchBuilders) {
440 Match match = mb.build();
441 FlowId flowId = FlowIdUtils.newFlowId(TABLE_ID, "cg", match);
444 .setPriority(Integer.valueOf(priority));
445 // If destination is External, the last Action ALLOW must be changed to goto NAT/External table.
446 if (isExternal(netElements.getDst())) {
447 flow.setInstructions(instructions(getGotoEgressNatInstruction()));
449 flow.setInstructions(instructions(applyActionIns(actionBuilderList)));
451 flowMap.writeFlow(netElements.getNodeId(), TABLE_ID, flow.build());
455 private String createBaseFlowId(Direction direction, CgPair cgPair, int priority) {
456 StringBuilder idb = new StringBuilder();
457 if (direction.equals(Direction.In)) {
458 idb.append(cgPair.sepg)
460 .append(cgPair.scgId)
464 .append(cgPair.dcgId)
468 idb.append(cgPair.depg)
470 .append(cgPair.dcgId)
474 .append(cgPair.scgId)
478 return idb.toString();
481 private MatchBuilder createBaseMatch(Direction direction, CgPair cgPair, IpPrefix sIpPrefix, IpPrefix dIpPrefix) {
482 MatchBuilder baseMatch = new MatchBuilder();
483 if (direction.equals(Direction.In)) {
484 addNxRegMatch(baseMatch,
485 RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.sepg)),
486 RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.scgId)),
487 RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.depg)),
488 RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.dcgId)));
489 if (sIpPrefix != null) {
490 baseMatch.setLayer3Match(createLayer3Match(sIpPrefix, true));
492 if (dIpPrefix != null) {
493 baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, true));
496 addNxRegMatch(baseMatch,
497 RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.depg)),
498 RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.dcgId)),
499 RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.sepg)),
500 RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.scgId)));
501 if (sIpPrefix != null) {
502 baseMatch.setLayer3Match(createLayer3Match(sIpPrefix, false));
504 if (dIpPrefix != null) {
505 baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, false));
511 private Layer3Match createLayer3Match(IpPrefix ipPrefix, boolean isSrc) {
512 if (ipPrefix.getIpv4Prefix() != null) {
514 return new Ipv4MatchBuilder().setIpv4Source(ipPrefix.getIpv4Prefix()).build();
516 return new Ipv4MatchBuilder().setIpv4Destination(ipPrefix.getIpv4Prefix()).build();
520 return new Ipv6MatchBuilder().setIpv6Source(ipPrefix.getIpv6Prefix()).build();
522 return new Ipv6MatchBuilder().setIpv6Destination(ipPrefix.getIpv6Prefix()).build();
527 // TODO: move to a common utils for all renderers
528 public List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>>
529 getActiveRulesBetweenEps(Policy policy, Endpoint consEp, Endpoint provEp) {
530 List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> rulesWithEpConstraints = new ArrayList<>();
531 if (policy.getRuleMap() != null) {
532 for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> cell : policy.getRuleMap().cellSet()) {
533 EndpointConstraint consEpConstraint = cell.getRowKey();
534 EndpointConstraint provEpConstraint = cell.getColumnKey();
535 if (epMatchesConstraint(consEp, consEpConstraint) && epMatchesConstraint(provEp, provEpConstraint)) {
536 rulesWithEpConstraints.add(cell);
540 return rulesWithEpConstraints;
543 private boolean epMatchesConstraint(Endpoint ep, EndpointConstraint constraint) {
544 List<ConditionName> epConditions = Collections.emptyList();
545 if (ep.getCondition() != null) {
546 epConditions = ep.getCondition();
548 return constraint.getConditionSet().matches(epConditions);
551 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction getGotoEgressNatInstruction() {
552 return gotoEgressNatInstruction;
555 private static org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.instruction.Instruction getGotoExternalInstruction() {
556 return gotoExternalInstruction;
560 private static class CgPair {
562 private final int sepg;
563 private final int depg;
564 private final int scgId;
565 private final int dcgId;
566 private final Set<IpPrefix> sIpPrefixes;
567 private final Set<IpPrefix> dIpPrefixes;
569 public CgPair(int sepg, int depg, int scgId, int dcgId, Set<IpPrefix> sIpPrefixes, Set<IpPrefix> dIpPrefixes) {
575 this.sIpPrefixes = sIpPrefixes;
576 this.dIpPrefixes = dIpPrefixes;
580 public int hashCode() {
581 final int prime = 31;
583 result = prime * result + ((dIpPrefixes == null) ? 0 : dIpPrefixes.hashCode());
584 result = prime * result + dcgId;
585 result = prime * result + depg;
586 result = prime * result + ((sIpPrefixes == null) ? 0 : sIpPrefixes.hashCode());
587 result = prime * result + scgId;
588 result = prime * result + sepg;
593 public boolean equals(Object obj) {
598 if (getClass() != obj.getClass())
600 CgPair other = (CgPair) obj;
601 if (dIpPrefixes == null) {
602 if (other.dIpPrefixes != null)
604 } else if (!dIpPrefixes.equals(other.dIpPrefixes))
606 if (dcgId != other.dcgId)
608 if (sIpPrefixes == null) {
609 if (other.sIpPrefixes != null)
611 } else if (!sIpPrefixes.equals(other.sIpPrefixes))
613 if (depg != other.depg)
615 if (scgId != other.scgId)
617 if (sepg != other.sepg)
623 public class NetworkElements {
627 EndpointFwdCtxOrdinals srcOrds;
628 EndpointFwdCtxOrdinals dstOrds;
630 public NetworkElements(Endpoint src, Endpoint dst, NodeId nodeId, OfContext ctx, PolicyInfo policyInfo) throws Exception {
633 this.nodeId = nodeId;
634 this.srcOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, src);
635 this.dstOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dst);
640 public EndpointFwdCtxOrdinals getSrcOrds() {
646 public EndpointFwdCtxOrdinals getDstOrds() {
651 public Endpoint getSrc() {
656 public Endpoint getDst() {
661 public NodeId getNodeId() {