use of org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Actions in project netvirt by opendaylight.
the class VpnServiceChainUtils method buildLportFlowDispForVpnToScf.
/**
* Creates the flow that sends the packet from the VPN to the SCF pipeline.
* This usually happens when there is an ScHop whose ingressPort is a
* VpnPseudoPort.
* <ul>
* <li>Matches: lportTag = vpnPseudoLPortTag, SI = 1
* <li>Actions: setMetadata(scfTag), Go to: UpSubFilter table
* </ul>
*/
public static FlowEntity buildLportFlowDispForVpnToScf(BigInteger dpId, int lportTag, long scfTag, short gotoTableId) {
List<InstructionInfo> instructions = new ArrayList<>();
List<ActionInfo> actionsInfos = new ArrayList<>();
actionsInfos.add(new ActionRegLoad(NxmNxReg2.class, 0, 31, scfTag));
instructions.add(new InstructionApplyActions(actionsInfos));
instructions.add(new InstructionGotoTable(gotoTableId));
String flowRef = getL3VpnToScfLportDispatcherFlowRef(lportTag);
List<MatchInfo> matches = buildMatchOnLportTagAndSI(lportTag, ServiceIndex.getIndex(NwConstants.SCF_SERVICE_NAME, NwConstants.SCF_SERVICE_INDEX));
return MDSALUtil.buildFlowEntity(dpId, NwConstants.LPORT_DISPATCHER_TABLE, flowRef, CloudServiceChainConstants.DEFAULT_SCF_FLOW_PRIORITY, flowRef, 0, 0, getCookieSCHop(scfTag), matches, instructions);
}
use of org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Actions in project netvirt by opendaylight.
the class VPNServiceChainHandler method programScfToVpnPipeline.
/**
* L3VPN Service chaining: It moves traffic from a ServiceChain to a L3VPN.
*
* @param vpnName Vpn Instance Name. Typicall the UUID
* @param scfTag ServiceChainForwarding Tag
* @param servChainTag ServiceChain Tag
* @param dpnId DpnId in which the egress pseudo logical port belongs
* @param vpnPseudoLportTag VpnPseudo Logical port tag
* @param isLastServiceChain Flag stating if there is no other ServiceChain
* using this VpnPseudoPort
* @param addOrRemove States if pipeline must be installed or removed
*/
public void programScfToVpnPipeline(String vpnName, long scfTag, int servChainTag, long dpnId, int vpnPseudoLportTag, boolean isLastServiceChain, int addOrRemove) {
// These Flows must be installed in the DPN where the last SF in the ServiceChain is located
// + ScForwardingTable (75): (This one is created and maintained by ScHopManager)
// - Match: scfTag + servChainId + lportTagOfvVSF Instr: VpnPseudoPortTag + SI=L3VPN + GOTO LPortDisp
// And these 2 flows must be installed in all Dpns where the Vpn is present:
// + LPortDisp (17):
// - Match: VpnPseudoPortTag + SI==L3VPN Instr: setVpnTag + GOTO FIB
// + FIB (21): (one entry per VrfEntry, and it is maintained by FibManager)
// - Match: vrfTag==vpnTag + eth_type=IPv4 + dst_ip Instr: Output DC-GW
//
LOG.info("L3VPN: Service Chaining programScfToVpnPipeline [Started]: Parameters Vpn Name: {} ", vpnName);
String rd = VpnServiceChainUtils.getVpnRd(dataBroker, vpnName);
if (rd == null || rd.isEmpty()) {
LOG.warn("programScfToVpnPipeline: Could not find Router-distinguisher for VPN {}. No further actions", vpnName);
return;
}
VpnInstanceOpDataEntry vpnInstance = getVpnInstance(rd);
LOG.debug("programScfToVpnPipeline: rd={}, lportTag={} ", rd, vpnPseudoLportTag);
// Find out the set of DPNs for the given VPN ID
if (vpnInstance != null) {
if (addOrRemove == NwConstants.ADD_FLOW || addOrRemove == NwConstants.DEL_FLOW && isLastServiceChain) {
Long vpnId = vpnInstance.getVpnId();
List<VpnToDpnList> vpnToDpnList = vpnInstance.getVpnToDpnList();
if (vpnToDpnList != null) {
List<BigInteger> dpns = new ArrayList<>();
for (VpnToDpnList dpnInVpn : vpnToDpnList) {
dpns.add(dpnInVpn.getDpnId());
}
if (!dpns.contains(BigInteger.valueOf(dpnId))) {
LOG.debug("Dpn {} is not included in the current VPN Footprint", dpnId);
dpns.add(BigInteger.valueOf(dpnId));
}
for (BigInteger dpn : dpns) {
VpnServiceChainUtils.programLPortDispatcherFlowForScfToVpn(mdsalManager, vpnId, dpn, vpnPseudoLportTag, addOrRemove);
}
} else {
LOG.debug("Could not find VpnToDpn list for VPN {} with rd {}", vpnName, rd);
}
}
// We need to keep a fake VpnInterface in the DPN where the last vSF (before the VpnPseudoPort) is
// located, because in case the last real VpnInterface is removed from that DPN, we still need
// the Fib table programmed there
String intfName = VpnServiceChainUtils.buildVpnPseudoPortIfName(dpnId, scfTag, servChainTag, vpnPseudoLportTag);
vpnFootprintService.updateVpnToDpnMapping(BigInteger.valueOf(dpnId), vpnName, rd, intfName, null, /*ipAddressSourceValuePair*/
addOrRemove == NwConstants.ADD_FLOW);
}
LOG.info("L3VPN: Service Chaining programScfToVpnPipeline [End]");
}
use of org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Actions in project netvirt by opendaylight.
the class NatUtil method getEgressActionsForInterface.
@Nonnull
public static List<ActionInfo> getEgressActionsForInterface(OdlInterfaceRpcService interfaceManager, String ifName, Long tunnelKey, int pos) {
LOG.debug("getEgressActionsForInterface : called for interface {}", ifName);
GetEgressActionsForInterfaceInputBuilder egressActionsBuilder = new GetEgressActionsForInterfaceInputBuilder().setIntfName(ifName);
if (tunnelKey != null) {
egressActionsBuilder.setTunnelKey(tunnelKey);
}
List<ActionInfo> listActionInfo = new ArrayList<>();
try {
Future<RpcResult<GetEgressActionsForInterfaceOutput>> result = interfaceManager.getEgressActionsForInterface(egressActionsBuilder.build());
RpcResult<GetEgressActionsForInterfaceOutput> rpcResult = result.get();
if (!rpcResult.isSuccessful()) {
LOG.error("getEgressActionsForInterface : RPC Call to Get egress actions for interface {} " + "returned with Errors {}", ifName, rpcResult.getErrors());
} else {
List<Action> actions = rpcResult.getResult().getAction();
for (Action action : actions) {
org.opendaylight.yang.gen.v1.urn.opendaylight.action.types.rev131112.action.Action actionClass = action.getAction();
if (actionClass instanceof OutputActionCase) {
listActionInfo.add(new ActionOutput(pos++, ((OutputActionCase) actionClass).getOutputAction().getOutputNodeConnector()));
} else if (actionClass instanceof PushVlanActionCase) {
listActionInfo.add(new ActionPushVlan(pos++));
} else if (actionClass instanceof SetFieldCase) {
if (((SetFieldCase) actionClass).getSetField().getVlanMatch() != null) {
int vlanVid = ((SetFieldCase) actionClass).getSetField().getVlanMatch().getVlanId().getVlanId().getValue();
listActionInfo.add(new ActionSetFieldVlanVid(pos++, vlanVid));
}
} else if (actionClass instanceof NxActionResubmitRpcAddGroupCase) {
Short tableId = ((NxActionResubmitRpcAddGroupCase) actionClass).getNxResubmit().getTable();
listActionInfo.add(new ActionNxResubmit(pos++, tableId));
} else if (actionClass instanceof NxActionRegLoadNodesNodeTableFlowApplyActionsCase) {
NxRegLoad nxRegLoad = ((NxActionRegLoadNodesNodeTableFlowApplyActionsCase) actionClass).getNxRegLoad();
listActionInfo.add(new ActionRegLoad(pos++, NxmNxReg6.class, nxRegLoad.getDst().getStart(), nxRegLoad.getDst().getEnd(), nxRegLoad.getValue().longValue()));
}
}
}
} catch (InterruptedException | ExecutionException e) {
LOG.error("Exception when egress actions for interface {}", ifName, e);
}
return listActionInfo;
}
use of org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Actions in project netvirt by opendaylight.
the class NaptEventHandler method handleEvent.
// TODO Clean up the exception handling
@SuppressWarnings("checkstyle:IllegalCatch")
public void handleEvent(final NAPTEntryEvent naptEntryEvent) {
/*
Flow programming logic of the OUTBOUND NAPT TABLE :
1) Get the internal IP address, port number, router ID from the event.
2) Use the NAPT service getExternalAddressMapping() to get the External IP and the port.
3) Build the flow for replacing the Internal IP and port with the External IP and port.
a) Write the matching criteria.
b) Match the router ID in the metadata.
d) Write the VPN ID to the metadata.
e) Write the other data.
f) Set the apply actions instruction with the action setfield.
4) Write the flow to the OUTBOUND NAPT Table and forward to FIB table for routing the traffic.
Flow programming logic of the INBOUND NAPT TABLE :
Same as Outbound table logic except that :
1) Build the flow for replacing the External IP and port with the Internal IP and port.
2) Match the VPN ID in the metadata.
3) Write the router ID to the metadata.
5) Write the flow to the INBOUND NAPT Table and forward to FIB table for routing the traffic.
*/
try {
Long routerId = naptEntryEvent.getRouterId();
LOG.trace("handleEvent : Time Elapsed before procesing snat ({}:{}) packet is {} ms," + "routerId: {},isPktProcessed:{}", naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), System.currentTimeMillis() - naptEntryEvent.getObjectCreationTime(), routerId, naptEntryEvent.isPktProcessed());
// Get the DPN ID
BigInteger dpnId = NatUtil.getPrimaryNaptfromRouterId(dataBroker, routerId);
long bgpVpnId = NatConstants.INVALID_ID;
if (dpnId == null) {
LOG.warn("handleEvent : dpnId is null. Assuming the router ID {} as the BGP VPN ID and proceeding....", routerId);
bgpVpnId = routerId;
LOG.debug("handleEvent : BGP VPN ID {}", bgpVpnId);
String vpnName = NatUtil.getRouterName(dataBroker, bgpVpnId);
String routerName = NatUtil.getRouterIdfromVpnInstance(dataBroker, vpnName);
if (routerName == null) {
LOG.error("handleEvent : Unable to find router for VpnName {}", vpnName);
return;
}
routerId = NatUtil.getVpnId(dataBroker, routerName);
LOG.debug("handleEvent : Router ID {}", routerId);
dpnId = NatUtil.getPrimaryNaptfromRouterId(dataBroker, routerId);
if (dpnId == null) {
LOG.error("handleEvent : dpnId is null for the router {}", routerId);
return;
}
}
if (naptEntryEvent.getOperation() == NAPTEntryEvent.Operation.ADD) {
LOG.debug("handleEvent : Inside Add operation of NaptEventHandler");
// Build and install the NAPT translation flows in the Outbound and Inbound NAPT tables
if (!naptEntryEvent.isPktProcessed()) {
// Get the External Gateway MAC Address
String extGwMacAddress = NatUtil.getExtGwMacAddFromRouterId(dataBroker, routerId);
if (extGwMacAddress != null) {
LOG.debug("handleEvent : External Gateway MAC address {} found for External Router ID {}", extGwMacAddress, routerId);
} else {
LOG.error("handleEvent : No External Gateway MAC address found for External Router ID {}", routerId);
return;
}
// Get the external network ID from the ExternalRouter model
Uuid networkId = NatUtil.getNetworkIdFromRouterId(dataBroker, routerId);
if (networkId == null) {
LOG.error("handleEvent : networkId is null");
return;
}
// Get the VPN ID from the ExternalNetworks model
Uuid vpnUuid = NatUtil.getVpnIdfromNetworkId(dataBroker, networkId);
if (vpnUuid == null) {
LOG.error("handleEvent : vpnUuid is null");
return;
}
Long vpnId = NatUtil.getVpnId(dataBroker, vpnUuid.getValue());
// Get the internal IpAddress, internal port number from the event
String internalIpAddress = naptEntryEvent.getIpAddress();
int internalPort = naptEntryEvent.getPortNumber();
SessionAddress internalAddress = new SessionAddress(internalIpAddress, internalPort);
NAPTEntryEvent.Protocol protocol = naptEntryEvent.getProtocol();
// Get the external IP address for the corresponding internal IP address
SessionAddress externalAddress = naptManager.getExternalAddressMapping(routerId, internalAddress, naptEntryEvent.getProtocol());
if (externalAddress == null) {
LOG.error("handleEvent : externalAddress is null");
return;
}
Long vpnIdFromExternalSubnet = getVpnIdFromExternalSubnet(routerId, externalAddress.getIpAddress());
if (vpnIdFromExternalSubnet != NatConstants.INVALID_ID) {
vpnId = vpnIdFromExternalSubnet;
}
// Added External Gateway MAC Address
Future<RpcResult<AddFlowOutput>> addFlowResult = buildAndInstallNatFlowsOptionalRpc(dpnId, NwConstants.INBOUND_NAPT_TABLE, vpnId, routerId, bgpVpnId, externalAddress, internalAddress, protocol, extGwMacAddress, true);
final BigInteger finalDpnId = dpnId;
final Long finalVpnId = vpnId;
final Long finalRouterId = routerId;
final long finalBgpVpnId = bgpVpnId;
Futures.addCallback(JdkFutureAdapters.listenInPoolThread(addFlowResult), new FutureCallback<RpcResult<AddFlowOutput>>() {
@Override
public void onSuccess(@Nullable RpcResult<AddFlowOutput> result) {
LOG.debug("handleEvent : Configured inbound rule for {} to {}", internalAddress, externalAddress);
Future<RpcResult<AddFlowOutput>> addFlowResult = buildAndInstallNatFlowsOptionalRpc(finalDpnId, NwConstants.OUTBOUND_NAPT_TABLE, finalVpnId, finalRouterId, finalBgpVpnId, internalAddress, externalAddress, protocol, extGwMacAddress, true);
Futures.addCallback(JdkFutureAdapters.listenInPoolThread(addFlowResult), new FutureCallback<RpcResult<AddFlowOutput>>() {
@Override
public void onSuccess(@Nullable RpcResult<AddFlowOutput> result) {
LOG.debug("handleEvent : Configured outbound rule, sending packet out" + "from {} to {}", internalAddress, externalAddress);
prepareAndSendPacketOut(naptEntryEvent, finalRouterId);
}
@Override
public void onFailure(@Nonnull Throwable throwable) {
LOG.error("handleEvent : Error configuring outbound " + "SNAT flows using RPC for SNAT connection from {} to {}", internalAddress, externalAddress);
}
}, MoreExecutors.directExecutor());
}
@Override
public void onFailure(@Nonnull Throwable throwable) {
LOG.error("handleEvent : Error configuring inbound SNAT flows " + "using RPC for SNAT connection from {} to {}", internalAddress, externalAddress);
}
}, MoreExecutors.directExecutor());
NatPacketProcessingState state = naptEntryEvent.getState();
if (state != null) {
state.setFlowInstalledTime(System.currentTimeMillis());
}
} else {
prepareAndSendPacketOut(naptEntryEvent, routerId);
}
LOG.trace("handleEvent : Time elapsed after Processsing snat ({}:{}) packet: {}ms,isPktProcessed:{} ", naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), System.currentTimeMillis() - naptEntryEvent.getObjectCreationTime(), naptEntryEvent.isPktProcessed());
} else {
LOG.debug("handleEvent : Inside delete Operation of NaptEventHandler");
removeNatFlows(dpnId, NwConstants.INBOUND_NAPT_TABLE, routerId, naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber());
LOG.info("handleEvent : exited for removeEvent for IP {}, port {}, routerID : {}", naptEntryEvent.getIpAddress(), naptEntryEvent.getPortNumber(), routerId);
}
} catch (Exception e) {
LOG.error("handleEvent :Exception in NaptEventHandler.handleEvent() payload {}", naptEntryEvent, e);
}
}
use of org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.access.control.list.rev160218.access.lists.acl.access.list.entries.ace.Actions in project netvirt by opendaylight.
the class ExternalRoutersListener method makeTunnelTableEntry.
private void makeTunnelTableEntry(BigInteger dpnId, long serviceId, long l3Vni, List<Instruction> customInstructions, WriteTransaction writeFlowInvTx, ProviderTypes extNwProvType) {
List<MatchInfo> mkMatches = new ArrayList<>();
LOG.debug("makeTunnelTableEntry : DpnId = {} and serviceId = {} and actions = {}", dpnId, serviceId, customInstructions);
if (NatUtil.isOpenStackVniSemanticsEnforcedForGreAndVxlan(elanManager, extNwProvType)) {
mkMatches.add(new MatchTunnelId(BigInteger.valueOf(l3Vni)));
} else {
mkMatches.add(new MatchTunnelId(BigInteger.valueOf(serviceId)));
}
Flow terminatingServiceTableFlowEntity = MDSALUtil.buildFlowNew(NwConstants.INTERNAL_TUNNEL_TABLE, getFlowRef(dpnId, NwConstants.INTERNAL_TUNNEL_TABLE, serviceId, ""), 5, String.format("%s:%d", "TST Flow Entry ", serviceId), 0, 0, COOKIE_TUNNEL.add(BigInteger.valueOf(serviceId)), mkMatches, customInstructions);
mdsalManager.addFlowToTx(dpnId, terminatingServiceTableFlowEntity, writeFlowInvTx);
}
Aggregations