- // Set<Endpoint> visitedEps = new HashSet<>();
- for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
- // visitedEps.add(srcEp);
- for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
-
- IndexedTenant tenant = ctx.getPolicyResolver().getTenant(srcEpgKey.getTenantId());
- EndpointGroup group = tenant.getEndpointGroup(srcEpgKey.getEgId());
- IntraGroupPolicy igp = group.getIntraGroupPolicy();
-
- if (igp == null || igp.equals(IntraGroupPolicy.Allow)) {
- for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(srcEpgKey)) {
- // mEPG ordinals
- // if(visitedEps.contains(dstEp)) {
- // continue;
- // }
- // visitedEps.add(dstEp);
- EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
- policyInfo, srcEp);
- EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
- policyInfo, dstEp);
- int depgId = dstEpFwdCxtOrds.getEpgId();
- int sepgId = srcEpFwdCxtOrds.getEpgId();
- flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(sepgId, depgId));
- flowMap.writeFlow(nodeId, TABLE_ID, allowSameEpg(depgId, sepgId));
+ allowSameEpg(nodeId, ofWriter);
+
+ // Write ARP flows per flood domain
+ for (Integer fdId : fdIds) {
+ ofWriter.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
+ }
+ }
+
+ private PathStatus resolveSourceEpgPolicy(OfWriter ofWriter, NetworkElements netElements, Policy directPolicy) {
+ isReversedPolicy = false;
+ directPathFlowsCreated = false;
+ reversePathFlowsCreated = false;
+
+ for (Cell<EndpointConstraint, EndpointConstraint, List<RuleGroup>> activeRulesByConstraints : getActiveRulesBetweenEps(
+ directPolicy, netElements.getDstEp(), netElements.getSrcEp())) {
+ Set<IpPrefix> sIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getRowKey()
+ .getL3EpPrefixes());
+ Set<IpPrefix> dIpPrefixes = Policy.getIpPrefixesFrom(activeRulesByConstraints.getColumnKey()
+ .getL3EpPrefixes());
+
+ int priority = 65000;
+ for (RuleGroup rg : activeRulesByConstraints.getValue()) {
+ TenantId tenantId = rg.getContractTenant().getId();
+ IndexedTenant tenant = ctx.getTenant(tenantId);
+ for (Rule rule : rg.getRules()) {
+
+ // Find all rules in the same traffic direction
+ List<Rule> sameDirectionRules = findRulesInSameDirection(rule, reversedActiveRules);
+ if (sameDirectionRules.isEmpty()) {
+ sameDirectionRules.add(rule);
+ }
+ sameDirectionRules = Ordering.from(TenantUtils.RULE_COMPARATOR)
+ .immutableSortedCopy(sameDirectionRules);
+
+ // Create flows for every pair of rules
+ for (Rule oppositeRule : sameDirectionRules) {
+
+ // Evaluate which rule has more specific matches
+ Rule ruleWithMatches = findRuleWithSpecificMatches(rule, oppositeRule, tenant);
+ Rule ruleWithActions = mergeRuleActions(rule, oppositeRule, tenant);
+ if (ruleWithMatches == null) {
+ LOG.trace("No matches found for pair of rules {}, {}", rule, oppositeRule);
+ continue;
+ }
+ if (ruleWithActions == null) {
+ LOG.trace("No actions found for pair of rules {}, {}", rule, oppositeRule);
+ continue;
+ }
+ PolicyPair policyPair = null;
+ if (rule.equals(ruleWithMatches)) {
+ policyPair = new PolicyPair(netElements.getDstEpOrdinals().getEpgId(),
+ netElements.getSrcEpOrdinals().getEpgId(), netElements.getDstEpOrdinals().getCgId(),
+ netElements.getSrcEpOrdinals().getCgId(), dIpPrefixes, sIpPrefixes,
+ netElements.getDstNodeId(), netElements.getSrcNodeId());
+ } else {
+ policyPair = new PolicyPair(netElements.getSrcEpOrdinals().getEpgId(),
+ netElements.getDstEpOrdinals().getEpgId(), netElements.getSrcEpOrdinals().getCgId(),
+ netElements.getDstEpOrdinals().getCgId(), sIpPrefixes, dIpPrefixes,
+ netElements.getSrcNodeId(), netElements.getDstNodeId());
+ }
+ LOG.trace("PolicyEnforcer: Visiting PolicyPair {} endpoints {} {}", policyPair,
+ netElements.getSrcEp().getKey(), netElements.getDstEp().getKey());
+
+ // Preserve original rule direction
+ Set<Direction> directions = getRuleDirections(rule);
+
+ for(Direction direction : directions) {
+
+ // Create list of matches/actions. Also creates chain flows when specific action requires it
+ List<MatchBuilder> inMatches = createMatches(Direction.In, policyPair, tenant,
+ ruleWithMatches);
+ List<MatchBuilder> outMatches = createMatches(Direction.Out, policyPair, tenant,
+ ruleWithMatches);
+
+ List<ActionBuilder> actions = createActions(ofWriter, netElements, direction,
+ policyPair, tenant, ruleWithActions, false);
+
+ // Compose flows
+ createFlows(inMatches, actions, netElements, ofWriter, priority);
+ createFlows(outMatches, actions, netElements, ofWriter, priority);
+
+ priority -= 1;
+
+ // Keep info about what direction has flows already created
+ if (direction.equals(Direction.In)) {
+ directPathFlowsCreated = true;
+ }
+ if (direction.equals(Direction.Out)) {
+ reversePathFlowsCreated = true;
+ }
+
+ // Fully resolved Ep groups are saved to prevent duplicates
+ if (directPathFlowsCreated && reversePathFlowsCreated) {
+ LOG.trace("Epg pair added: {}, {} ", netElements.getSrcEpg(), netElements.getDstEpg());
+ resolvedEpgPairs.put(netElements.getSrcEpg(), netElements.getDstEpg());
+ }
+ }