/*
- * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
+ * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 which accompanies this distribution,
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.PolicyManager.FlowMap;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.FlowUtils.RegMatch;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.flow.OrdinalFactory.EndpointFwdCtxOrdinals;
+import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.node.SwitchManager;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.Action;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.AllowAction;
import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.ClassificationResult;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.inventory.rev130819.tables.table.FlowBuilder;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.Match;
import org.opendaylight.yang.gen.v1.urn.opendaylight.flow.types.rev131026.flow.MatchBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ConditionName;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg1;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg2;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg3;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg5;
import org.opendaylight.yang.gen.v1.urn.opendaylight.openflowjava.nx.match.rev140421.NxmNxReg7;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.overlay.rev150105.TunnelTypeVxlan;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
* unless specifically allowed by policy
*/
public class PolicyEnforcer extends FlowTable {
- protected static final Logger LOG =
- LoggerFactory.getLogger(PolicyEnforcer.class);
+
+ protected static final Logger LOG = LoggerFactory.getLogger(PolicyEnforcer.class);
public static final short TABLE_ID = 3;
flowMap.writeFlow(nodeId, TABLE_ID, dropFlow(Integer.valueOf(1), null));
- flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(nodeId));
+ NodeConnectorId tunPort = SwitchManager.getTunnelPort(nodeId, TunnelTypeVxlan.class);
+ if (tunPort != null) {
+ flowMap.writeFlow(nodeId, TABLE_ID, allowFromTunnel(tunPort));
+ }
HashSet<CgPair> visitedPairs = new HashSet<>();
+ // Used for ARP flows
+ Set<Integer> fdIds = new HashSet<>();
+
for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
Set<EgKey> peers = policyInfo.getPeers(srcEpgKey);
for (EgKey dstEpgKey : peers) {
for (Endpoint dstEp : ctx.getEndpointManager().getEndpointsForGroup(dstEpgKey)) {
// mEPG ordinals
- EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, srcEp);
- EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dstEp);
+ EndpointFwdCtxOrdinals srcEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
+ policyInfo, srcEp);
+ EndpointFwdCtxOrdinals dstEpFwdCxtOrds = OrdinalFactory.getEndpointFwdCtxOrdinals(ctx,
+ policyInfo, dstEp);
int dcgId = dstEpFwdCxtOrds.getCgId();
int depgId = dstEpFwdCxtOrds.getEpgId();
int scgId = srcEpFwdCxtOrds.getCgId();
int sepgId = srcEpFwdCxtOrds.getEpgId();
+ NetworkElements netElements = new NetworkElements(srcEp, dstEp, nodeId, ctx, policyInfo);
+ fdIds.add(srcEpFwdCxtOrds.getFdId());
List<ConditionName> conds = ctx.getEndpointManager().getCondsForEndpoint(srcEp);
ConditionGroup scg = policyInfo.getEgCondGroup(srcEpgKey, conds);
conds = ctx.getEndpointManager().getCondsForEndpoint(dstEp);
ConditionGroup dcg = policyInfo.getEgCondGroup(dstEpgKey, conds);
+ Policy policy = policyInfo.getPolicy(dstEpgKey, srcEpgKey);
+ List<RuleGroup> rgs = policy.getRules(dcg, scg);
CgPair p = new CgPair(depgId, sepgId, dcgId, scgId);
if (visitedPairs.contains(p))
continue;
visitedPairs.add(p);
- syncPolicy(flowMap, nodeId, policyInfo,
- p, dstEpgKey, srcEpgKey, dcg, scg);
+ syncPolicy(flowMap, netElements, rgs, p);
- //Reverse
+ // Reverse
+ policy = policyInfo.getPolicy(srcEpgKey, dstEpgKey);
+ rgs = policy.getRules(scg, dcg);
p = new CgPair(sepgId, depgId, scgId, dcgId);
if (visitedPairs.contains(p))
continue;
visitedPairs.add(p);
- syncPolicy(flowMap, nodeId, policyInfo,
- p, srcEpgKey, dstEpgKey, scg, dcg);
+ syncPolicy(flowMap, netElements, rgs, p);
}
}
}
}
// Allow same EPG
-// Set<Endpoint> visitedEps = new HashSet<>();
+ // Set<Endpoint> visitedEps = new HashSet<>();
for (Endpoint srcEp : ctx.getEndpointManager().getEndpointsForNode(nodeId)) {
-// visitedEps.add(srcEp);
+ // visitedEps.add(srcEp);
for (EgKey srcEpgKey : ctx.getEndpointManager().getEgKeysForEndpoint(srcEp)) {
IndexedTenant tenant = ctx.getPolicyResolver().getTenant(srcEpgKey.getTenantId());
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);
+ // 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));
}
}
+ // Write ARP flows per flood domain.
+ for (Integer fdId : fdIds) {
+ flowMap.writeFlow(nodeId, TABLE_ID, createArpFlow(fdId));
+ }
+ }
+
+ private Flow createArpFlow(Integer fdId) {
+
+ Long etherType = FlowUtils.ARP;
+ // L2 Classifier so 20,000 for now
+ Integer priority = 20000;
+ FlowId flowid = new FlowId(new StringBuilder().append("arp")
+ .append("|")
+ .append(etherType)
+ .append("|")
+ .append(fdId)
+ .toString());
+
+ MatchBuilder mb = new MatchBuilder().setEthernetMatch(FlowUtils.ethernetMatch(null, null, etherType));
+
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg5.class, Long.valueOf(fdId)));
+
+ Flow flow = base().setPriority(priority)
+ .setId(flowid)
+ .setMatch(mb.build())
+ .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))))
+ .build();
+ return flow;
}
private Flow allowSameEpg(int sepgId, int depgId) {
- FlowId flowId = new FlowId(new StringBuilder()
- .append("intraallow|")
- .append(sepgId).toString());
- MatchBuilder mb = new MatchBuilder();
- addNxRegMatch(mb,
- RegMatch.of(NxmNxReg0.class, Long.valueOf(sepgId)),
- RegMatch.of(NxmNxReg2.class, Long.valueOf(depgId)));
- FlowBuilder flow = base()
- .setId(flowId)
- .setMatch(mb.build())
- .setPriority(65000)
- .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
- return flow.build();
+
+ FlowId flowId = new FlowId(new StringBuilder().append("intraallow|").append(sepgId).toString());
+ MatchBuilder mb = new MatchBuilder();
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg0.class, Long.valueOf(sepgId)),
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(depgId)));
+ FlowBuilder flow = base().setId(flowId)
+ .setMatch(mb.build())
+ .setPriority(65000)
+ .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
+ return flow.build();
}
- private Flow allowFromTunnel(NodeId nodeId) {
- NodeConnectorId tunPort =
- ctx.getSwitchManager().getTunnelPort(nodeId);
- if (tunPort == null)
- return null;
+ private Flow allowFromTunnel(NodeConnectorId tunPort) {
FlowId flowId = new FlowId("tunnelallow");
- MatchBuilder mb = new MatchBuilder()
- .setInPort(tunPort);
- addNxRegMatch(mb,
- RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
- FlowBuilder flow = base()
- .setId(flowId)
- .setMatch(mb.build())
- .setPriority(65000)
- .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
+ MatchBuilder mb = new MatchBuilder().setInPort(tunPort);
+ addNxRegMatch(mb, RegMatch.of(NxmNxReg1.class, Long.valueOf(0xffffff)));
+ FlowBuilder flow = base().setId(flowId)
+ .setMatch(mb.build())
+ .setPriority(65000)
+ .setInstructions(instructions(applyActionIns(nxOutputRegAction(NxmNxReg7.class))));
return flow.build();
}
- private void syncPolicy(FlowMap flowMap, NodeId nodeId,
- PolicyInfo policyInfo,
- CgPair p, EgKey sepg, EgKey depg,
- ConditionGroup scg, ConditionGroup dcg)
- throws Exception {
- // XXX - TODO raise an exception for rules between the same
- // endpoint group that are asymmetric
- Policy policy = policyInfo.getPolicy(sepg, depg);
- List<RuleGroup> rgs = policy.getRules(scg, dcg);
-
+ private void syncPolicy(FlowMap flowMap, NetworkElements netElements, List<RuleGroup> rgs, CgPair p) {
int priority = 65000;
for (RuleGroup rg : rgs) {
TenantId tenantId = rg.getContractTenant().getId();
IndexedTenant tenant = ctx.getPolicyResolver().getTenant(tenantId);
for (Rule r : rg.getRules()) {
- syncDirection(flowMap, nodeId, tenant,
- p, r, Direction.In, priority);
- syncDirection(flowMap, nodeId, tenant,
- p, r, Direction.Out, priority);
+ syncDirection(flowMap, netElements, tenant, p, r, Direction.In, priority);
+ syncDirection(flowMap, netElements, tenant, p, r, Direction.Out, priority);
priority -= 1;
}
* determined first by the value of the order parameter, with the lower
* order actions being applied first; for Actions with either the same order
* or no order, ordering is lexicographical by name.
- *
*/
private static class ActionRefComparator implements Comparator<ActionRef> {
+
public static final ActionRefComparator INSTANCE = new ActionRefComparator();
@Override
public int compare(ActionRef arg0, ActionRef arg1) {
return ComparisonChain.start()
- .compare(arg0.getOrder(), arg1.getOrder(),
- Ordering.natural().nullsLast())
- .compare(arg0.getName().getValue(), arg1.getName().getValue(),
- Ordering.natural().nullsLast())
- .result();
+ .compare(arg0.getOrder(), arg1.getOrder(), Ordering.natural().nullsLast())
+ .compare(arg0.getName().getValue(), arg1.getName().getValue(), Ordering.natural().nullsLast())
+ .result();
}
}
- private void syncDirection(FlowMap flowMap, NodeId nodeId, IndexedTenant contractTenant,
- CgPair cgPair, Rule rule, Direction direction, int priority) {
+ private void syncDirection(FlowMap flowMap, NetworkElements netElements, IndexedTenant contractTenant, CgPair cgPair, Rule rule,
+ Direction direction, int priority) {
/*
* Create the ordered action list. The implicit action is "allow", and
* is therefore always in the list
* incorporating operational policy for actions
*/
- //TODO: can pass Comparator ActionRefComparator to List constructor, rather than referencing in sort
- List<ActionBuilder> abl = new ArrayList<ActionBuilder>();
+ // TODO: can pass Comparator ActionRefComparator to List constructor, rather than
+ // referencing in sort
+ List<ActionBuilder> actionBuilderList = new ArrayList<ActionBuilder>();
if (rule.getActionRef() != null) {
/*
* Pre-sort by references using order, then name
List<ActionRef> arl = new ArrayList<ActionRef>(rule.getActionRef());
Collections.sort(arl, ActionRefComparator.INSTANCE);
- for (ActionRef ar : arl) {
- ActionInstance ai = contractTenant.getAction(ar.getName());
- if (ai == null) {
+ for (ActionRef actionRule : arl) {
+ ActionInstance actionInstance = contractTenant.getAction(actionRule.getName());
+ if (actionInstance == null) {
// XXX TODO fail the match and raise an exception
- LOG.warn("Action instance {} not found",
- ar.getName().getValue());
+ LOG.warn("Action instance {} not found", actionRule.getName().getValue());
return;
}
- Action act = SubjectFeatures.getAction(ai.getActionDefinitionId());
- if (act == null) {
+ Action action = SubjectFeatures.getAction(actionInstance.getActionDefinitionId());
+ if (action == null) {
// XXX TODO fail the match and raise an exception
- LOG.warn("Action definition {} not found",
- ai.getActionDefinitionId().getValue());
+ LOG.warn("Action definition {} not found", actionInstance.getActionDefinitionId().getValue());
return;
}
Map<String, Object> params = new HashMap<>();
- if (ai.getParameterValue() != null) {
- for (ParameterValue v : ai.getParameterValue()) {
+ if (actionInstance.getParameterValue() != null) {
+ for (ParameterValue v : actionInstance.getParameterValue()) {
if (v.getName() == null)
continue;
if (v.getIntValue() != null) {
/*
* Convert the GBP Action to one or more OpenFlow Actions
*/
- abl = act.updateAction(abl, params, ar.getOrder());
+ actionBuilderList = action.updateAction(actionBuilderList, params, actionRule.getOrder(),netElements);
}
- }
- else {
+ } else {
Action act = SubjectFeatures.getAction(AllowAction.DEFINITION.getId());
- abl = act.updateAction(abl, new HashMap<String, Object>(), 0);
+ actionBuilderList = act.updateAction(actionBuilderList, new HashMap<String, Object>(), 0, netElements);
}
+ Map<String, ParameterValue> paramsFromClassifier = new HashMap<>();
+ Set<ClassifierDefinitionId> classifiers = new HashSet<>();
for (ClassifierRef cr : rule.getClassifierRef()) {
- if (cr.getDirection() != null &&
- !cr.getDirection().equals(Direction.Bidirectional) &&
- !cr.getDirection().equals(direction)) {
+ if (cr.getDirection() != null && !cr.getDirection().equals(Direction.Bidirectional)
+ && !cr.getDirection().equals(direction)) {
continue;
}
- StringBuilder idb = new StringBuilder();
// XXX - TODO - implement connection tracking (requires openflow
// extension and data plane support - in 2.4. Will need to handle
// case where we are working with mix of nodes.
- MatchBuilder baseMatch = new MatchBuilder();
+ ClassifierInstance ci = contractTenant.getClassifier(cr.getName());
+ if (ci == null) {
+ // XXX TODO fail the match and raise an exception
+ LOG.warn("Classifier instance {} not found", cr.getName().getValue());
+ return;
+ }
+ Classifier cfier = SubjectFeatures.getClassifier(ci.getClassifierDefinitionId());
+ if (cfier == null) {
+ // XXX TODO fail the match and raise an exception
+ LOG.warn("Classifier definition {} not found", ci.getClassifierDefinitionId().getValue());
+ return;
+ }
+ classifiers.add(new ClassifierDefinitionId(ci.getClassifierDefinitionId()));
+ for (ParameterValue v : ci.getParameterValue()) {
- if (direction.equals(Direction.In)) {
- idb.append(cgPair.sepg)
+ if (v.getIntValue() != null) {
+ paramsFromClassifier.put(v.getName().getValue(), v);
+ } else if (v.getStringValue() != null) {
+ paramsFromClassifier.put(v.getName().getValue(), v);
+ } else if (v.getRangeValue() != null) {
+ paramsFromClassifier.put(v.getName().getValue(), v);
+ }
+ }
+ }
+ List<Map<String, ParameterValue>> derivedParamsByName = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(paramsFromClassifier);
+
+ for (Map<String, ParameterValue> params : derivedParamsByName) {
+ for (ClassifierDefinitionId clDefId : classifiers) {
+ Classifier classifier = SubjectFeatures.getClassifier(clDefId);
+ StringBuilder idb = new StringBuilder();
+ // XXX - TODO - implement connection tracking (requires openflow
+ // extension and data plane support - in 2.4. Will need to handle
+ // case where we are working with mix of nodes.
+
+ MatchBuilder baseMatch = new MatchBuilder();
+ if (direction.equals(Direction.In)) {
+ idb.append(cgPair.sepg)
.append("|")
.append(cgPair.scgId)
.append("|")
.append(cgPair.dcgId)
.append("|")
.append(priority);
- addNxRegMatch(baseMatch,
- RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.sepg)),
- RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.scgId)),
- RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.depg)),
- RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.dcgId)));
- } else {
- idb.append(cgPair.depg)
+ addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.sepg)),
+ RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.scgId)),
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.depg)),
+ RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.dcgId)));
+ } else {
+ idb.append(cgPair.depg)
.append("|")
.append(cgPair.dcgId)
.append("|")
.append(cgPair.scgId)
.append("|")
.append(priority);
- addNxRegMatch(baseMatch,
- RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.depg)),
- RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.dcgId)),
- RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.sepg)),
- RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.scgId)));
- }
-
- ClassifierInstance ci = contractTenant.getClassifier(cr.getName());
- if (ci == null) {
- // XXX TODO fail the match and raise an exception
- LOG.warn("Classifier instance {} not found",
- cr.getName().getValue());
- return;
- }
- Classifier cfier = SubjectFeatures
- .getClassifier(ci.getClassifierDefinitionId());
- if (cfier == null) {
- // XXX TODO fail the match and raise an exception
- LOG.warn("Classifier definition {} not found",
- ci.getClassifierDefinitionId().getValue());
- return;
- }
+ addNxRegMatch(baseMatch, RegMatch.of(NxmNxReg0.class, Long.valueOf(cgPair.depg)),
+ RegMatch.of(NxmNxReg1.class, Long.valueOf(cgPair.dcgId)),
+ RegMatch.of(NxmNxReg2.class, Long.valueOf(cgPair.sepg)),
+ RegMatch.of(NxmNxReg3.class, Long.valueOf(cgPair.scgId)));
+ }
- Map<String,ParameterValue> params = new HashMap<>();
- for (ParameterValue v : ci.getParameterValue()) {
+ List<MatchBuilder> matches = new ArrayList<>();
+ matches.add(baseMatch);
- if (v.getIntValue() != null) {
- params.put(v.getName().getValue(), v);
- } else if (v.getStringValue() != null) {
- params.put(v.getName().getValue(), v);
- } else if (v.getRangeValue() != null) {
- params.put(v.getName().getValue(), v);
- }
- }
- List<Map<String, ParameterValue>> derivedParams = ParamDerivator.ETHER_TYPE_DERIVATOR.deriveParameter(params);
- for (Map<String, ParameterValue> flowParams : derivedParams) {
- List<MatchBuilder> matches = Collections.singletonList(new MatchBuilder(baseMatch.build()));
- ClassificationResult result = cfier.updateMatch(matches, flowParams);
- if(!result.isSuccessfull()) {
- //TODO consider different handling.
+ ClassificationResult result = classifier.updateMatch(matches, params);
+ if (!result.isSuccessfull()) {
+ // TODO consider different handling.
throw new IllegalArgumentException(result.getErrorMessage());
}
String baseId = idb.toString();
for (MatchBuilder match : result.getMatchBuilders()) {
Match m = match.build();
FlowId flowId = new FlowId(baseId + "|" + m.toString());
- flow.setMatch(m)
+ flow.setMatch(m)
.setId(flowId)
.setPriority(Integer.valueOf(priority))
- .setInstructions(instructions(applyActionIns(abl)));
- flowMap.writeFlow(nodeId, TABLE_ID, flow.build());
-
-
+ .setInstructions(instructions(applyActionIns(actionBuilderList)));
+ flowMap.writeFlow(netElements.getNodeId(), TABLE_ID, flow.build());
}
}
}
@Immutable
private static class CgPair {
+
private final int sepg;
private final int depg;
private final int scgId;
return true;
}
}
+
+ public class NetworkElements {
+ Endpoint src;
+ Endpoint dst;
+ NodeId nodeId;
+ EndpointFwdCtxOrdinals srcOrds;
+ EndpointFwdCtxOrdinals dstOrds;
+
+ public NetworkElements(Endpoint src, Endpoint dst, NodeId nodeId, OfContext ctx, PolicyInfo policyInfo) throws Exception {
+ this.src=src;
+ this.dst=dst;
+ this.nodeId = nodeId;
+ this.srcOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, src);
+ this.dstOrds=OrdinalFactory.getEndpointFwdCtxOrdinals(ctx, policyInfo, dst);
+ }
+
+
+
+ public EndpointFwdCtxOrdinals getSrcOrds() {
+ return srcOrds;
+ }
+
+
+
+ public EndpointFwdCtxOrdinals getDstOrds() {
+ return dstOrds;
+ }
+
+
+ public Endpoint getSrc() {
+ return src;
+ }
+
+
+ public Endpoint getDst() {
+ return dst;
+ }
+
+
+ public NodeId getNodeId() {
+ return nodeId;
+ }
+
+
+ }
}