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.applyActionIns;
13 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.instructions;
14 import static org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.nxOutputRegAction;
16 import java.util.ArrayList;
17 import java.util.Collections;
18 import java.util.Comparator;
19 import java.util.HashMap;
20 import java.util.HashSet;
21 import java.util.List;
25 import javax.annotation.concurrent.Immutable;
27 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.OfContext;
28 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
29 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
30 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
31 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
32 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action;
33 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
34 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassificationResult;
35 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Classifier;
36 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ParamDerivator;
37 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.SubjectFeatures;
38 import org.opendaylight.groupbasedpolicy.resolver.ConditionGroup;
39 import org.opendaylight.groupbasedpolicy.resolver.EgKey;
40 import org.opendaylight.groupbasedpolicy.resolver.EndpointConstraint;
41 import org.opendaylight.groupbasedpolicy.resolver.IndexedTenant;
42 import org.opendaylight.groupbasedpolicy.resolver.Policy;
43 import org.opendaylight.groupbasedpolicy.resolver.PolicyInfo;
44 import org.opendaylight.groupbasedpolicy.resolver.RuleGroup;
45 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.list.ActionBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.FlowId;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.Flow;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.subject.Rule;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ActionInstance;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeConnectorId;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.NodeId;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.Layer3Match;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv4MatchBuilder;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.model.match.types.rev131026.match.layer._3.match.Ipv6MatchBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg0;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
80 import com.google.common.collect.ComparisonChain;
81 import com.google.common.collect.Ordering;
82 import com.google.common.collect.Table.Cell;
85 * Manage the table that enforces policy on the traffic. Traffic is denied
86 * unless specifically allowed by policy
88 public class PolicyEnforcer extends FlowTable {
90 protected static final Logger LOG = LoggerFactory.getLogger(PolicyEnforcer.class);
92 public static final short TABLE_ID = 3;
94 public PolicyEnforcer(OfContext ctx) {
99 public short getTableId() {
104 public void sync(NodeId nodeId, PolicyInfo policyInfo, FlowMap flowMap) throws Exception {
106 flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
108 NodeConnectorId tunPort = SwitchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class);
109 if (tunPort != null) {
110 flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(tunPort));
113 HashSet<CgPair> visitedPairs = new HashSet<>();
115 // Used for ARP flows
116 Set<Integer> fdIds = new HashSet<>();
118 for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
119 for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
120 Set<EgKey> peers = policyInfo.getPeers(srcEpgKey);
121 for (EgKey dstEpgKey : peers) {
122 for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(dstEpgKey)) {
124 EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
126 EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
128 int dcgId = dstEpFwdCxtOrds.getCgId();
129 int depgId = dstEpFwdCxtOrds.getEpgId();
130 int scgId = srcEpFwdCxtOrds.getCgId();
131 int sepgId = srcEpFwdCxtOrds.getEpgId();
132 NetworkElements netElements = new NetworkElements(srcEp, dstEp, nodeId, ctx, policyInfo);
133 fdIds.add(srcEpFwdCxtOrds.getFdId());
135 Policy policy = policyInfo.getPolicy(dstEpgKey, srcEpgKey);
136 for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints: getActiveRulesBetweenEps(policy, dstEp, srcEp)) {
137 Set<IpPrefix> sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey()
139 Set<IpPrefix> dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey()
141 CgPair p = new CgPair(depgId, sepgId, dcgId, scgId, dIpPrefixes, sIpPrefixes);
142 if (visitedPairs.contains(p))
145 syncPolicy(flowMap, netElements, activeRulesByConstraints.getValue(), p);
149 policy = policyInfo.getPolicy(srcEpgKey, dstEpgKey);
150 for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints : getActiveRulesBetweenEps(policy, srcEp, dstEp)) {
151 Set<IpPrefix> sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey()
153 Set<IpPrefix> dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey()
155 CgPair p = new CgPair(sepgId, depgId, scgId, dcgId, sIpPrefixes, dIpPrefixes);
156 if (visitedPairs.contains(p))
159 syncPolicy(flowMap, netElements, activeRulesByConstraints.getValue(), p);
167 // Set<Endpoint> visitedEps = new HashSet<>();
168 for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
169 // visitedEps.add(srcEp);
170 for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
172 IndexedTenant tenant = ctx.getPolicyResolver().getTenant(srcEpgKey.getTenantId());
173 EndpointGroup group = tenant.getEndpointGroup(srcEpgKey.getEgId());
174 IntraGroupPolicy igp = group.getIntraGroupPolicy();
176 if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
177 for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(srcEpgKey)) {
179 // if(visitedEps.contains(dstEp)) {
182 // visitedEps.add(dstEp);
183 EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
185 EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
187 int depgId = dstEpFwdCxtOrds.getEpgId();
188 int sepgId = srcEpFwdCxtOrds.getEpgId();
189 flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(sepgId, depgId));
190 flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(depgId, sepgId));
196 // Write ARP flows per flood domain.
197 for (Integer fdId : fdIds) {
198 flowMap.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
202 private Flow createArpFlow(Integer fdId) {
204 Long etherType = FlowUtils.ARP;
205 // L2 Classifier so 20,000 for now
206 Integer priority = 20000;
207 FlowId flowid = new FlowId(new StringBuilder().append("arp")
214 MatchBuilder mb = new MatchBuilder().setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType));
216 addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(fdId)));
218 Flow flow = base().setPriority(priority)
220 .setMatch(mb.build())
221 .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))))
226 private Flow allowSameEpg(int sepgId, int depgId) {
228 FlowId flowId = new FlowId(new StringBuilder().append("intraallow|").append(sepgId).toString());
229 MatchBuilder mb = new MatchBuilder();
230 addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, Long.valueOf(sepgId)),
231 RegMatch.of(NxmNxReg2.class, Long.valueOf(depgId)));
232 FlowBuilder flow = base().setId(flowId)
233 .setMatch(mb.build())
235 .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
239 private Flow allowFromTunnel(NodeConnectorId tunPort) {
241 FlowId flowId = new FlowId("tunnelallow");
242 MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
243 addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
244 FlowBuilder flow = base().setId(flowId)
245 .setMatch(mb.build())
247 .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
252 private void syncPolicy(FlowMap flowMap, NetworkElements netElements, List<RuleGroup> rgs, CgPair p) {
253 int priority = 65000;
254 for (RuleGroup rg : rgs) {
255 TenantId tenantId = rg.getContractTenant().getId();
256 IndexedTenant tenant = ctx.getPolicyResolver().getTenant(tenantId);
257 for (Rule r : rg.getRules()) {
258 syncDirection(flowMap, netElements, tenant, p, r, Direction.In, priority);
259 syncDirection(flowMap, netElements, tenant, p, r, Direction.Out, priority);
267 * Private internal class for ordering Actions in Rules. The order is
268 * determined first by the value of the order parameter, with the lower
269 * order actions being applied first; for Actions with either the same order
270 * or no order, ordering is lexicographical by name.
272 private static class ActionRefComparator implements Comparator<ActionRef> {
274 public static final ActionRefComparator INSTANCE = new ActionRefComparator();
277 public int compare(ActionRef arg0, ActionRef arg1) {
278 return ComparisonChain.start()
279 .compare(arg0.getOrder(), arg1.getOrder(), Ordering.natural().nullsLast())
280 .compare(arg0.getName().getValue(), arg1.getName().getValue(), Ordering.natural().nullsLast())
286 private void syncDirection(FlowMap flowMap, NetworkElements netElements, IndexedTenant contractTenant, CgPair cgPair, Rule rule,
287 Direction direction, int priority) {
289 * Create the ordered action list. The implicit action is "allow", and
290 * is therefore always in the list
292 * TODO: revisit implicit vs. default for "allow" TODO: look into
293 * incorporating operational policy for actions
296 // TODO: can pass Comparator ActionRefComparator to List constructor, rather than
297 // referencing in sort
298 List<ActionBuilder> actionBuilderList = new ArrayList<ActionBuilder>();
299 if (rule.getActionRef() != null) {
301 * Pre-sort by references using order, then name
303 List<ActionRef> arl = new ArrayList<ActionRef>(rule.getActionRef());
304 Collections.sort(arl, ActionRefComparator.INSTANCE);
306 for (ActionRef actionRule : arl) {
307 ActionInstance actionInstance = contractTenant.getAction(actionRule.getName());
308 if (actionInstance == null) {
309 // XXX TODO fail the match and raise an exception
310 LOG.warn("Action instance {} not found", actionRule.getName().getValue());
313 Action action = SubjectFeatures.getAction(actionInstance.getActionDefinitionId());
314 if (action == null) {
315 // XXX TODO fail the match and raise an exception
316 LOG.warn("Action definition {} not found", actionInstance.getActionDefinitionId().getValue());
320 Map<String, Object> params = new HashMap<>();
321 if (actionInstance.getParameterValue() != null) {
322 for (ParameterValue v : actionInstance.getParameterValue()) {
323 if (v.getName() == null)
325 if (v.getIntValue() != null) {
326 params.put(v.getName().getValue(), v.getIntValue());
327 } else if (v.getStringValue() != null) {
328 params.put(v.getName().getValue(), v.getStringValue());
333 * Convert the GBP Action to one or more OpenFlow Actions
335 actionBuilderList = action.updateAction(actionBuilderList, params, actionRule.getOrder(),netElements);
338 Action act = SubjectFeatures.getAction(AllowAction.DEFINITION.getId());
339 actionBuilderList = act.updateAction(actionBuilderList, new HashMap<String, Object>(), 0, netElements);
342 Map<String, ParameterValue> paramsFromClassifier = new HashMap<>();
343 Set<ClassifierDefinitionId> classifiers = new HashSet<>();
344 for (ClassifierRef cr : rule.getClassifierRef()) {
345 if (cr.getDirection() != null && !cr.getDirection().equals(Direction.Bidirectional)
346 && !cr.getDirection().equals(direction)) {
350 // XXX - TODO - implement connection tracking (requires openflow
351 // extension and data plane support - in 2.4. Will need to handle
352 // case where we are working with mix of nodes.
354 ClassifierInstance ci = contractTenant.getClassifier(cr.getName());
356 // XXX TODO fail the match and raise an exception
357 LOG.warn("Classifier instance {} not found", cr.getName().getValue());
360 Classifier cfier = SubjectFeatures.getClassifier(ci.getClassifierDefinitionId());
362 // XXX TODO fail the match and raise an exception
363 LOG.warn("Classifier definition {} not found", ci.getClassifierDefinitionId().getValue());
366 classifiers.add(new ClassifierDefinitionId(ci.getClassifierDefinitionId()));
367 for (ParameterValue v : ci.getParameterValue()) {
369 if (v.getIntValue() != null) {
370 paramsFromClassifier.put(v.getName().getValue(), v);
371 } else if (v.getStringValue() != null) {
372 paramsFromClassifier.put(v.getName().getValue(), v);
373 } else if (v.getRangeValue() != null) {
374 paramsFromClassifier.put(v.getName().getValue(), v);
378 List<Map<String, ParameterValue>> derivedParamsByName = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(paramsFromClassifier);
380 for (Map<String, ParameterValue> params : derivedParamsByName) {
381 for (ClassifierDefinitionId clDefId : classifiers) {
382 // XXX - TODO - implement connection tracking (requires openflow
383 // extension and data plane support - in 2.4. Will need to handle
384 // case where we are working with mix of nodes.
386 List<MatchBuilder> matches = new ArrayList<>();
387 if (cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
388 matches.add(createBaseMatch(direction, cgPair, null, null));
389 } else if (!cgPair.sIpPrefixes.isEmpty() && cgPair.dIpPrefixes.isEmpty()) {
390 for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
391 matches.add(createBaseMatch(direction, cgPair, sIpPrefix, null));
393 } else if (cgPair.sIpPrefixes.isEmpty() && !cgPair.dIpPrefixes.isEmpty()) {
394 for (IpPrefix dIpPrefix : cgPair.sIpPrefixes) {
395 matches.add(createBaseMatch(direction, cgPair, null, dIpPrefix));
398 for (IpPrefix sIpPrefix : cgPair.sIpPrefixes) {
399 for (IpPrefix dIpPrefix : cgPair.sIpPrefixes) {
400 matches.add(createBaseMatch(direction, cgPair, sIpPrefix, dIpPrefix));
405 Classifier classifier = SubjectFeatures.getClassifier(clDefId);
406 ClassificationResult result = classifier.updateMatch(matches, params);
407 if (!result.isSuccessfull()) {
408 // TODO consider different handling.
409 throw new IllegalArgumentException(result.getErrorMessage());
411 String baseId = createBaseFlowId(direction, cgPair, priority);
412 FlowBuilder flow = base().setPriority(Integer.valueOf(priority));
413 for (MatchBuilder match : result.getMatchBuilders()) {
414 Match m = match.build();
415 FlowId flowId = new FlowId(baseId + "|" + m.toString());
418 .setPriority(Integer.valueOf(priority))
419 .setInstructions(instructions(applyActionIns(actionBuilderList)));
420 flowMap.writeFlow(netElements.getNodeId(), TABLE_ID, flow.build());
426 private String createBaseFlowId(Direction direction, CgPair cgPair, int priority) {
427 StringBuilder idb = new StringBuilder();
428 if (direction.equals(Direction.In)) {
429 idb.append(cgPair.sepg)
431 .append(cgPair.scgId)
435 .append(cgPair.dcgId)
439 idb.append(cgPair.depg)
441 .append(cgPair.dcgId)
445 .append(cgPair.scgId)
449 return idb.toString();
452 private MatchBuilder createBaseMatch(Direction direction, CgPair cgPair, IpPrefix sIpPrefix, IpPrefix dIpPrefix) {
453 MatchBuilder baseMatch = new MatchBuilder();
454 if (direction.equals(Direction.In)) {
455 addNxRegMatch(baseMatch,
456 RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.sepg)),
457 RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.scgId)),
458 RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.depg)),
459 RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.dcgId)));
460 if (sIpPrefix != null) {
461 baseMatch.setLayer3Match(createLayer3Match(sIpPrefix, true));
463 if (dIpPrefix != null) {
464 baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, true));
467 addNxRegMatch(baseMatch,
468 RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.depg)),
469 RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.dcgId)),
470 RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.sepg)),
471 RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.scgId)));
472 if (sIpPrefix != null) {
473 baseMatch.setLayer3Match(createLayer3Match(sIpPrefix, false));
475 if (dIpPrefix != null) {
476 baseMatch.setLayer3Match(createLayer3Match(dIpPrefix, false));
482 private Layer3Match createLayer3Match(IpPrefix ipPrefix, boolean isSrc) {
483 if (ipPrefix.getIpv4Prefix() != null) {
485 return new Ipv4MatchBuilder().setIpv4Source(ipPrefix.getIpv4Prefix()).build();
487 return new Ipv4MatchBuilder().setIpv4Destination(ipPrefix.getIpv4Prefix()).build();
491 return new Ipv6MatchBuilder().setIpv6Source(ipPrefix.getIpv6Prefix()).build();
493 return new Ipv6MatchBuilder().setIpv6Destination(ipPrefix.getIpv6Prefix()).build();
498 // TODO: move to a common utils for all renderers
499 public List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>>
500 getActiveRulesBetweenEps(Policy policy, Endpoint consEp, Endpoint provEp) {
501 List<Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>>> rulesWithEpConstraints = new ArrayList<>();
502 if (policy.getRuleMap() != null) {
503 for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> cell : policy.getRuleMap().cellSet()) {
504 EndpointConstraint consEpConstraint = cell.getRowKey();
505 EndpointConstraint provEpConstraint = cell.getColumnKey();
506 if (epMatchesConstraint(consEp, consEpConstraint) && epMatchesConstraint(provEp, provEpConstraint)) {
507 rulesWithEpConstraints.add(cell);
511 return rulesWithEpConstraints;
514 private boolean epMatchesConstraint(Endpoint ep, EndpointConstraint constraint) {
515 List<ConditionName> epConditions = Collections.emptyList();
516 if (ep.getCondition() != null) {
517 epConditions = ep.getCondition();
519 return constraint.getConditionSet().matches(epConditions);
523 private static class CgPair {
525 private final int sepg;
526 private final int depg;
527 private final int scgId;
528 private final int dcgId;
529 private final Set<IpPrefix> sIpPrefixes;
530 private final Set<IpPrefix> dIpPrefixes;
532 public CgPair(int sepg, int depg, int scgId, int dcgId, Set<IpPrefix> sIpPrefixes, Set<IpPrefix> dIpPrefixes) {
538 this.sIpPrefixes = sIpPrefixes;
539 this.dIpPrefixes = dIpPrefixes;
543 public int hashCode() {
544 final int prime = 31;
546 result = prime * result + ((dIpPrefixes == null) ? 0 : dIpPrefixes.hashCode());
547 result = prime * result + dcgId;
548 result = prime * result + depg;
549 result = prime * result + ((sIpPrefixes == null) ? 0 : sIpPrefixes.hashCode());
550 result = prime * result + scgId;
551 result = prime * result + sepg;
556 public boolean equals(Object obj) {
561 if (getClass() != obj.getClass())
563 CgPair other = (CgPair) obj;
564 if (dIpPrefixes == null) {
565 if (other.dIpPrefixes != null)
567 } else if (!dIpPrefixes.equals(other.dIpPrefixes))
569 if (dcgId != other.dcgId)
571 if (sIpPrefixes == null) {
572 if (other.sIpPrefixes != null)
574 } else if (!sIpPrefixes.equals(other.sIpPrefixes))
576 if (depg != other.depg)
578 if (scgId != other.scgId)
580 if (sepg != other.sepg)
586 public class NetworkElements {
590 EndpointFwdCtxOrdinals srcOrds;
591 EndpointFwdCtxOrdinals dstOrds;
593 public NetworkElements(Endpoint src, Endpoint dst, NodeId nodeId, OfContext ctx, PolicyInfo policyInfo) throws Exception {
596 this.nodeId = nodeId;
597 this.srcOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, src);
598 this.dstOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dst);
603 public EndpointFwdCtxOrdinals getSrcOrds() {
609 public EndpointFwdCtxOrdinals getDstOrds() {
614 public Endpoint getSrc() {
619 public Endpoint getDst() {
624 public NodeId getNodeId() {