+
+ @Override
+ public Future<RpcResult<java.lang.Void>> createTerminatingServiceActions(final CreateTerminatingServiceActionsInput input) {
+ LOG.info("create terminatingServiceAction on DpnId = {} for service id {} and instructions {}", input.getDpnId() , input.getServiceId(), input.getInstruction());
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ int serviceId = input.getServiceId() ;
+ List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+ byte[] vxLANHeader = new byte[] {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+ // Flags Byte
+ byte Flags = (byte) 0x08;
+ vxLANHeader[0] = Flags;
+
+ // Extract the serviceId details and imprint on the VxLAN Header
+ vxLANHeader[4] = (byte) (serviceId >> 16);
+ vxLANHeader[5] = (byte) (serviceId >> 8);
+ vxLANHeader[6] = (byte) (serviceId >> 0);
+
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[] {
+ new BigInteger(1, vxLANHeader),
+ MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID }));
+
+ Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(ITMConstants.INTERNAL_TUNNEL_TABLE,
+ getFlowRef(ITMConstants.INTERNAL_TUNNEL_TABLE,serviceId), 5, String.format("%s:%d","ITM Flow Entry ",serviceId),
+ 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(serviceId)),mkMatches, input.getInstruction());
+
+ ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
+ Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
+
+ @Override
+ public void onSuccess(Void aVoid) {
+ result.set(RpcResultBuilder.<Void>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ String msg = String.format("Unable to install terminating service flow for %s", input.getDpnId());
+ LOG.error("create terminating service actions failed. {}. {}", msg, error);
+ result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+ }
+ });
+ result.set(RpcResultBuilder.<Void>success().build());
+ return result;
+ }
+
+ @Override
+ public Future<RpcResult<java.lang.Void>> removeTerminatingServiceActions(final RemoveTerminatingServiceActionsInput input) {
+ LOG.info("remove terminatingServiceActions called with DpnId = {} and serviceId = {}", input.getDpnId(), input.getServiceId());
+ final SettableFuture<RpcResult<Void>> result = SettableFuture.create();
+ Flow terminatingServiceTableFlow = MDSALUtil.buildFlowNew(ITMConstants.INTERNAL_TUNNEL_TABLE,
+ getFlowRef(ITMConstants.INTERNAL_TUNNEL_TABLE,input.getServiceId()), 5, String.format("%s:%d","ITM Flow Entry ",input.getServiceId()),
+ 0, 0, ITMConstants.COOKIE_ITM.add(BigInteger.valueOf(input.getServiceId())),getTunnelMatchesForServiceId(input.getServiceId()), null );
+
+ ListenableFuture<Void> installFlowResult = mdsalManager.installFlow(input.getDpnId(), terminatingServiceTableFlow);
+ Futures.addCallback(installFlowResult, new FutureCallback<Void>(){
+
+ @Override
+ public void onSuccess(Void aVoid) {
+ result.set(RpcResultBuilder.<Void>success().build());
+ }
+
+ @Override
+ public void onFailure(Throwable error) {
+ String msg = String.format("Unable to remove terminating service flow for %s", input.getDpnId());
+ LOG.error("remove terminating service actions failed. {}. {}", msg, error);
+ result.set(RpcResultBuilder.<Void>failed().withError(RpcError.ErrorType.APPLICATION, msg, error).build());
+ }
+ });
+ result.set(RpcResultBuilder.<Void>success().build());
+
+ return result ;
+ }
+
+ public List<MatchInfo> getTunnelMatchesForServiceId(int serviceId) {
+ List<MatchInfo> mkMatches = new ArrayList<MatchInfo>();
+ byte[] vxLANHeader = new byte[]{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+
+ // Flags Byte
+ byte Flags = (byte) 0x08;
+ vxLANHeader[0] = Flags;
+
+ // Extract the serviceId details and imprint on the VxLAN Header
+ vxLANHeader[4] = (byte) (serviceId >> 16);
+ vxLANHeader[5] = (byte) (serviceId >> 8);
+ vxLANHeader[6] = (byte) (serviceId >> 0);
+
+ // Matching metadata
+ mkMatches.add(new MatchInfo(MatchFieldType.tunnel_id, new BigInteger[]{
+ new BigInteger(1, vxLANHeader),
+ MetaDataUtil.METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID}));
+
+ return mkMatches;
+ }
+
+ private String getFlowRef(long termSvcTable, int svcId) {
+ return new StringBuffer().append(termSvcTable).append(svcId).toString();
+ }
+