Result set type is TYPE_FORWARD_ONLY

本文介绍了一种在SSH框架中解决分页问题的有效方法。通过在XML配置文件中设置特定属性,可以启用滚动结果集,从而实现更灵活的数据分页处理。

在ssh分页中出现的问题

 解决方法:在xml文件中进行配置:

<property name="hibernate.jdbc.use_scrollable_resultset">true</property>


--------------------------------------------------------------------------- TypeError Traceback (most recent call last) Cell In[14], line 23 21 # 3. 导出ONNX模型 22 onnx_path = "/home/weiqi.xie/hyh/WiFo-main/weights/wifo_base_D1.onnx" ---> 23 torch.onnx.export( 24 model, # 要导出的模型 25 input, # 模型输入示例 26 onnx_path, # 输出文件路径 27 opset_version=18, 28 do_constant_folding=True, 29 dynamic_axes = dynamic_axes, 30 input_names=['input'], # 输入节点名称 31 output_names=['output'], # 输出节点名称 32 ) 33 print(f"ONNX模型已保存至: {onnx_path}") File ~/miniconda3/lib/python3.13/site-packages/torch/onnx/__init__.py:424, in export(model, args, f, kwargs, export_params, verbose, input_names, output_names, opset_version, dynamic_axes, keep_initializers_as_inputs, dynamo, external_data, dynamic_shapes, custom_translation_table, report, optimize, verify, profile, dump_exported_program, artifacts_dir, fallback, training, operator_export_type, do_constant_folding, custom_opsets, export_modules_as_functions, autograd_inlining) 418 if dynamic_shapes: 419 raise ValueError( 420 "The exporter only supports dynamic shapes " 421 "through parameter dynamic_axes when dynamo=False." 422 ) --> 424 export( 425 model, 426 args, 427 f, # type: ignore[arg-type] 428 kwargs=kwargs, 429 export_params=export_params, 430 verbose=verbose is True, 431 input_names=input_names, 432 output_names=output_names, 433 opset_version=opset_version, 434 dynamic_axes=dynamic_axes, 435 keep_initializers_as_inputs=keep_initializers_as_inputs, 436 training=training, 437 operator_export_type=operator_export_type, 438 do_constant_folding=do_constant_folding, 439 custom_opsets=custom_opsets, 440 export_modules_as_functions=export_modules_as_functions, 441 autograd_inlining=autograd_inlining, 442 ) 443 return None File ~/miniconda3/lib/python3.13/site-packages/torch/onnx/utils.py:522, in export(model, args, f, kwargs, export_params, verbose, training, input_names, output_names, operator_export_type, opset_version, do_constant_folding, dynamic_axes, keep_initializers_as_inputs, custom_opsets, export_modules_as_functions, autograd_inlining) 519 if kwargs is not None: 520 args = args + (kwargs,) --> 522 _export( 523 model, 524 args, 525 f, 526 export_params, 527 verbose, 528 training, 529 input_names, 530 output_names, 531 operator_export_type=operator_export_type, 532 opset_version=opset_version, 533 do_constant_folding=do_constant_folding, 534 dynamic_axes=dynamic_axes, 535 keep_initializers_as_inputs=keep_initializers_as_inputs, 536 custom_opsets=custom_opsets, 537 export_modules_as_functions=export_modules_as_functions, 538 autograd_inlining=autograd_inlining, 539 ) 541 return None File ~/miniconda3/lib/python3.13/site-packages/torch/onnx/utils.py:1457, in _export(model, args, f, export_params, verbose, training, input_names, output_names, operator_export_type, export_type, opset_version, do_constant_folding, dynamic_axes, keep_initializers_as_inputs, fixed_batch_size, custom_opsets, add_node_names, onnx_shape_inference, export_modules_as_functions, autograd_inlining) 1454 dynamic_axes = {} 1455 _validate_dynamic_axes(dynamic_axes, model, input_names, output_names) -> 1457 graph, params_dict, torch_out = _model_to_graph( 1458 model, 1459 args, 1460 verbose, 1461 input_names, 1462 output_names, 1463 operator_export_type, 1464 val_do_constant_folding, 1465 fixed_batch_size=fixed_batch_size, 1466 training=training, 1467 dynamic_axes=dynamic_axes, 1468 ) 1470 if custom_opsets is None: 1471 custom_opsets = {} File ~/miniconda3/lib/python3.13/site-packages/torch/onnx/utils.py:1080, in _model_to_graph(model, args, verbose, input_names, output_names, operator_export_type, do_constant_folding, _disable_torch_constant_prop, fixed_batch_size, training, dynamic_axes) 1077 args = (args,) 1079 model = _pre_trace_quant_model(model, args) -> 1080 graph, params, torch_out, module = _create_jit_graph(model, args) 1081 params_dict = _get_named_param_dict(graph, params) 1083 try: File ~/miniconda3/lib/python3.13/site-packages/torch/onnx/utils.py:964, in _create_jit_graph(model, args) 959 graph = _C._propagate_and_assign_input_shapes( 960 graph, flattened_args, param_count_list, False, False 961 ) 962 return graph, params, torch_out, None --> 964 graph, torch_out = _trace_and_get_graph_from_model(model, args) 965 _C._jit_pass_onnx_lint(graph) 966 state_dict = torch.jit._unique_state_dict(model) File ~/miniconda3/lib/python3.13/site-packages/torch/onnx/utils.py:871, in _trace_and_get_graph_from_model(model, args) 869 prev_autocast_cache_enabled = torch.is_autocast_cache_enabled() 870 torch.set_autocast_cache_enabled(False) --> 871 trace_graph, torch_out, inputs_states = torch.jit._get_trace_graph( 872 model, 873 args, 874 strict=False, 875 _force_outplace=False, 876 _return_inputs_states=True, 877 ) 878 torch.set_autocast_cache_enabled(prev_autocast_cache_enabled) 880 warn_on_static_input_change(inputs_states) File ~/miniconda3/lib/python3.13/site-packages/torch/jit/_trace.py:1504, in _get_trace_graph(f, args, kwargs, strict, _force_outplace, return_inputs, _return_inputs_states) 1502 if not isinstance(args, tuple): 1503 args = (args,) -> 1504 outs = ONNXTracedModule( 1505 f, strict, _force_outplace, return_inputs, _return_inputs_states 1506 )(*args, **kwargs) 1507 return outs File ~/miniconda3/lib/python3.13/site-packages/torch/nn/modules/module.py:1773, in Module._wrapped_call_impl(self, *args, **kwargs) 1771 return self._compiled_call_impl(*args, **kwargs) # type: ignore[misc] 1772 else: -> 1773 return self._call_impl(*args, **kwargs) File ~/miniconda3/lib/python3.13/site-packages/torch/nn/modules/module.py:1784, in Module._call_impl(self, *args, **kwargs) 1779 # If we don't have any hooks, we want to skip the rest of the logic in 1780 # this function, and just call forward. 1781 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks 1782 or _global_backward_pre_hooks or _global_backward_hooks 1783 or _global_forward_hooks or _global_forward_pre_hooks): -> 1784 return forward_call(*args, **kwargs) 1786 result = None 1787 called_always_called_hooks = set() File ~/miniconda3/lib/python3.13/site-packages/torch/jit/_trace.py:138, in ONNXTracedModule.forward(self, *args) 135 else: 136 return tuple(out_vars) --> 138 graph, _out = torch._C._create_graph_by_tracing( 139 wrapper, 140 in_vars + module_state, 141 _create_interpreter_name_lookup_fn(), 142 self.strict, 143 self._force_outplace, 144 ) 146 if self._return_inputs: 147 return graph, outs[0], ret_inputs[0] File ~/miniconda3/lib/python3.13/site-packages/torch/jit/_trace.py:129, in ONNXTracedModule.forward.<locals>.wrapper(*args) 127 if self._return_inputs_states: 128 inputs_states.append(_unflatten(in_args, in_desc)) --> 129 outs.append(self.inner(*trace_inputs)) 130 if self._return_inputs_states: 131 inputs_states[0] = (inputs_states[0], trace_inputs) File ~/miniconda3/lib/python3.13/site-packages/torch/nn/modules/module.py:1773, in Module._wrapped_call_impl(self, *args, **kwargs) 1771 return self._compiled_call_impl(*args, **kwargs) # type: ignore[misc] 1772 else: -> 1773 return self._call_impl(*args, **kwargs) File ~/miniconda3/lib/python3.13/site-packages/torch/nn/modules/module.py:1784, in Module._call_impl(self, *args, **kwargs) 1779 # If we don't have any hooks, we want to skip the rest of the logic in 1780 # this function, and just call forward. 1781 if not (self._backward_hooks or self._backward_pre_hooks or self._forward_hooks or self._forward_pre_hooks 1782 or _global_backward_pre_hooks or _global_backward_hooks 1783 or _global_forward_hooks or _global_forward_pre_hooks): -> 1784 return forward_call(*args, **kwargs) 1786 result = None 1787 called_always_called_hooks = set() File ~/miniconda3/lib/python3.13/site-packages/torch/nn/modules/module.py:1763, in Module._slow_forward(self, *input, **kwargs) 1761 recording_scopes = False 1762 try: -> 1763 result = self.forward(*input, **kwargs) 1764 finally: 1765 if recording_scopes: File ~/hyh/WiFo-main/src/model.py:661, in WiFo.forward(self, imgs, mask_ratio, mask_strategy, seed, data) 659 def forward(self, imgs, mask_ratio=0.5, mask_strategy='random',seed=None, data='none'): --> 661 imgs = torch.stack(imgs).squeeze(1) 663 snr_db = 20 664 noise_power = torch.mean(imgs ** 2) * 10 ** (-snr_db / 10) TypeError: stack(): argument 'tensors' (position 1) must be tuple of Tensors, not Tensor
09-03
报错如下,如何修改》// Functor implementations -*- C++ -*- // Copyright (C) 2001-2014 Free Software Foundation, Inc. // // This file is part of the GNU ISO C++ Library. This library is free // software; you can redistribute it and/or modify it under the // terms of the GNU General Public License as published by the // Free Software Foundation; either version 3, or (at your option) // any later version. // This library is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // Under Section 7 of GPL version 3, you are granted additional // permissions described in the GCC Runtime Library Exception, version // 3.1, as published by the Free Software Foundation. // You should have received a copy of the GNU General Public License and // a copy of the GCC Runtime Library Exception along with this program; // see the files COPYING3 and COPYING.RUNTIME respectively. If not, see // <http://www.gnu.org/licenses/>. /* * * Copyright (c) 1994 * Hewlett-Packard Company * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Hewlett-Packard Company makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. * * * Copyright (c) 1996-1998 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, * provided that the above copyright notice appear in all copies and * that both that copyright notice and this permission notice appear * in supporting documentation. Silicon Graphics makes no * representations about the suitability of this software for any * purpose. It is provided "as is" without express or implied warranty. */ /** @file bits/stl_function.h * This is an internal header file, included by other library headers. * Do not attempt to use it directly. @headername{functional} */ #ifndef _STL_FUNCTION_H #define _STL_FUNCTION_H 1 #if __cplusplus > 201103L #include <bits/move.h> #endif namespace std _GLIBCXX_VISIBILITY(default) { _GLIBCXX_BEGIN_NAMESPACE_VERSION // 20.3.1 base classes /** @defgroup functors Function Objects * @ingroup utilities * * Function objects, or @e functors, are objects with an @c operator() * defined and accessible. They can be passed as arguments to algorithm * templates and used in place of a function pointer. Not only is the * resulting expressiveness of the library increased, but the generated * code can be more efficient than what you might write by hand. When we * refer to @a functors, then, generally we include function pointers in * the description as well. * * Often, functors are only created as temporaries passed to algorithm * calls, rather than being created as named variables. * * Two examples taken from the standard itself follow. To perform a * by-element addition of two vectors @c a and @c b containing @c double, * and put the result in @c a, use * \code * transform (a.begin(), a.end(), b.begin(), a.begin(), plus<double>()); * \endcode * To negate every element in @c a, use * \code * transform(a.begin(), a.end(), a.begin(), negate<double>()); * \endcode * The addition and negation functions will be inlined directly. * * The standard functors are derived from structs named @c unary_function * and @c binary_function. These two classes contain nothing but typedefs, * to aid in generic (template) programming. If you write your own * functors, you might consider doing the same. * * @{ */ /** * This is one of the @link functors functor base classes@endlink. */ template<typename _Arg, typename _Result> struct unary_function { /// @c argument_type is the type of the argument typedef _Arg argument_type; /// @c result_type is the return type typedef _Result result_type; }; /** * This is one of the @link functors functor base classes@endlink. */ template<typename _Arg1, typename _Arg2, typename _Result> struct binary_function { /// @c first_argument_type is the type of the first argument typedef _Arg1 first_argument_type; /// @c second_argument_type is the type of the second argument typedef _Arg2 second_argument_type; /// @c result_type is the return type typedef _Result result_type; }; /** @} */ // 20.3.2 arithmetic /** @defgroup arithmetic_functors Arithmetic Classes * @ingroup functors * * Because basic math often needs to be done during an algorithm, * the library provides functors for those operations. See the * documentation for @link functors the base classes@endlink * for examples of their use. * * @{ */ #if __cplusplus > 201103L struct __is_transparent; // undefined template<typename _Tp = void> struct plus; template<typename _Tp = void> struct minus; template<typename _Tp = void> struct multiplies; template<typename _Tp = void> struct divides; template<typename _Tp = void> struct modulus; template<typename _Tp = void> struct negate; #endif /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct plus : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x + __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct minus : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x - __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct multiplies : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x * __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct divides : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x / __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct modulus : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x % __y; } }; /// One of the @link arithmetic_functors math functors@endlink. template<typename _Tp> struct negate : public unary_function<_Tp, _Tp> { _Tp operator()(const _Tp& __x) const { return -__x; } }; #if __cplusplus > 201103L #define __cpp_lib_transparent_operators 201210 //#define __cpp_lib_generic_associative_lookup 201304 template<> struct plus<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) + std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) + std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) + std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct minus<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) - std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) - std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) - std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct multiplies<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) * std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) * std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) * std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct divides<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) / std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) / std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) / std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct modulus<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) % std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) % std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) % std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link arithmetic_functors math functors@endlink. template<> struct negate<void> { template <typename _Tp> auto operator()(_Tp&& __t) const noexcept(noexcept(-std::forward<_Tp>(__t))) -> decltype(-std::forward<_Tp>(__t)) { return -std::forward<_Tp>(__t); } typedef __is_transparent is_transparent; }; #endif /** @} */ // 20.3.3 comparisons /** @defgroup comparison_functors Comparison Classes * @ingroup functors * * The library provides six wrapper functors for all the basic comparisons * in C++, like @c <. * * @{ */ #if __cplusplus > 201103L template<typename _Tp = void> struct equal_to; template<typename _Tp = void> struct not_equal_to; template<typename _Tp = void> struct greater; template<typename _Tp = void> struct less; template<typename _Tp = void> struct greater_equal; template<typename _Tp = void> struct less_equal; #endif /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct equal_to : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x == __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct not_equal_to : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x != __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct greater : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x > __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct less : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x < __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct greater_equal : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x >= __y; } }; /// One of the @link comparison_functors comparison functors@endlink. template<typename _Tp> struct less_equal : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x <= __y; } }; #if __cplusplus > 201103L /// One of the @link comparison_functors comparison functors@endlink. template<> struct equal_to<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) == std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) == std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) == std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct not_equal_to<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) != std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) != std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) != std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct greater<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) > std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) > std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) > std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct less<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) < std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) < std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) < std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct greater_equal<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) >= std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) >= std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) >= std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link comparison_functors comparison functors@endlink. template<> struct less_equal<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) <= std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) <= std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) <= std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; #endif /** @} */ // 20.3.4 logical operations /** @defgroup logical_functors Boolean Operations Classes * @ingroup functors * * Here are wrapper functors for Boolean operations: @c &&, @c ||, * and @c !. * * @{ */ #if __cplusplus > 201103L template<typename _Tp = void> struct logical_and; template<typename _Tp = void> struct logical_or; template<typename _Tp = void> struct logical_not; #endif /// One of the @link logical_functors Boolean operations functors@endlink. template<typename _Tp> struct logical_and : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x && __y; } }; /// One of the @link logical_functors Boolean operations functors@endlink. template<typename _Tp> struct logical_or : public binary_function<_Tp, _Tp, bool> { bool operator()(const _Tp& __x, const _Tp& __y) const { return __x || __y; } }; /// One of the @link logical_functors Boolean operations functors@endlink. template<typename _Tp> struct logical_not : public unary_function<_Tp, bool> { bool operator()(const _Tp& __x) const { return !__x; } }; #if __cplusplus > 201103L /// One of the @link logical_functors Boolean operations functors@endlink. template<> struct logical_and<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) && std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) && std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) && std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link logical_functors Boolean operations functors@endlink. template<> struct logical_or<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) || std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) || std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) || std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; /// One of the @link logical_functors Boolean operations functors@endlink. template<> struct logical_not<void> { template <typename _Tp> auto operator()(_Tp&& __t) const noexcept(noexcept(!std::forward<_Tp>(__t))) -> decltype(!std::forward<_Tp>(__t)) { return !std::forward<_Tp>(__t); } typedef __is_transparent is_transparent; }; #endif /** @} */ #if __cplusplus > 201103L template<typename _Tp = void> struct bit_and; template<typename _Tp = void> struct bit_or; template<typename _Tp = void> struct bit_xor; template<typename _Tp = void> struct bit_not; #endif // _GLIBCXX_RESOLVE_LIB_DEFECTS // DR 660. Missing Bitwise Operations. template<typename _Tp> struct bit_and : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x & __y; } }; template<typename _Tp> struct bit_or : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x | __y; } }; template<typename _Tp> struct bit_xor : public binary_function<_Tp, _Tp, _Tp> { _Tp operator()(const _Tp& __x, const _Tp& __y) const { return __x ^ __y; } }; template<typename _Tp> struct bit_not : public unary_function<_Tp, _Tp> { _Tp operator()(const _Tp& __x) const { return ~__x; } }; #if __cplusplus > 201103L template <> struct bit_and<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) & std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) & std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) & std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; template <> struct bit_or<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) | std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) | std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) | std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; template <> struct bit_xor<void> { template <typename _Tp, typename _Up> auto operator()(_Tp&& __t, _Up&& __u) const noexcept(noexcept(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u))) -> decltype(std::forward<_Tp>(__t) ^ std::forward<_Up>(__u)) { return std::forward<_Tp>(__t) ^ std::forward<_Up>(__u); } typedef __is_transparent is_transparent; }; template <> struct bit_not<void> { template <typename _Tp> auto operator()(_Tp&& __t) const noexcept(noexcept(~std::forward<_Tp>(__t))) -> decltype(~std::forward<_Tp>(__t)) { return ~std::forward<_Tp>(__t); } typedef __is_transparent is_transparent; }; #endif // 20.3.5 negators /** @defgroup negators Negators * @ingroup functors * * The functions @c not1 and @c not2 each take a predicate functor * and return an instance of @c unary_negate or * @c binary_negate, respectively. These classes are functors whose * @c operator() performs the stored predicate function and then returns * the negation of the result. * * For example, given a vector of integers and a trivial predicate, * \code * struct IntGreaterThanThree * : public std::unary_function<int, bool> * { * bool operator() (int x) { return x > 3; } * }; * * std::find_if (v.begin(), v.end(), not1(IntGreaterThanThree())); * \endcode * The call to @c find_if will locate the first index (i) of @c v for which * <code>!(v[i] > 3)</code> is true. * * The not1/unary_negate combination works on predicates taking a single * argument. The not2/binary_negate combination works on predicates which * take two arguments. * * @{ */ /// One of the @link negators negation functors@endlink. template<typename _Predicate> class unary_negate : public unary_function<typename _Predicate::argument_type, bool> { protected: _Predicate _M_pred; public: explicit unary_negate(const _Predicate& __x) : _M_pred(__x) { } bool operator()(const typename _Predicate::argument_type& __x) const { return !_M_pred(__x); } }; /// One of the @link negators negation functors@endlink. template<typename _Predicate> inline unary_negate<_Predicate> not1(const _Predicate& __pred) { return unary_negate<_Predicate>(__pred); } /// One of the @link negators negation functors@endlink. template<typename _Predicate> class binary_negate : public binary_function<typename _Predicate::first_argument_type, typename _Predicate::second_argument_type, bool> { protected: _Predicate _M_pred; public: explicit binary_negate(const _Predicate& __x) : _M_pred(__x) { } bool operator()(const typename _Predicate::first_argument_type& __x, const typename _Predicate::second_argument_type& __y) const { return !_M_pred(__x, __y); } }; /// One of the @link negators negation functors@endlink. template<typename _Predicate> inline binary_negate<_Predicate> not2(const _Predicate& __pred) { return binary_negate<_Predicate>(__pred); } /** @} */ // 20.3.7 adaptors pointers functions /** @defgroup pointer_adaptors Adaptors for pointers to functions * @ingroup functors * * The advantage of function objects over pointers to functions is that * the objects in the standard library declare nested typedefs describing * their argument and result types with uniform names (e.g., @c result_type * from the base classes @c unary_function and @c binary_function). * Sometimes those typedefs are required, not just optional. * * Adaptors are provided to turn pointers to unary (single-argument) and * binary (double-argument) functions into function objects. The * long-winded functor @c pointer_to_unary_function is constructed with a * function pointer @c f, and its @c operator() called with argument @c x * returns @c f(x). The functor @c pointer_to_binary_function does the same * thing, but with a double-argument @c f and @c operator(). * * The function @c ptr_fun takes a pointer-to-function @c f and constructs * an instance of the appropriate functor. * * @{ */ /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg, typename _Result> class pointer_to_unary_function : public unary_function<_Arg, _Result> { protected: _Result (*_M_ptr)(_Arg); public: pointer_to_unary_function() { } explicit pointer_to_unary_function(_Result (*__x)(_Arg)) : _M_ptr(__x) { } _Result operator()(_Arg __x) const { return _M_ptr(__x); } }; /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg, typename _Result> inline pointer_to_unary_function<_Arg, _Result> ptr_fun(_Result (*__x)(_Arg)) { return pointer_to_unary_function<_Arg, _Result>(__x); } /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg1, typename _Arg2, typename _Result> class pointer_to_binary_function : public binary_function<_Arg1, _Arg2, _Result> { protected: _Result (*_M_ptr)(_Arg1, _Arg2); public: pointer_to_binary_function() { } explicit pointer_to_binary_function(_Result (*__x)(_Arg1, _Arg2)) : _M_ptr(__x) { } _Result operator()(_Arg1 __x, _Arg2 __y) const { return _M_ptr(__x, __y); } }; /// One of the @link pointer_adaptors adaptors for function pointers@endlink. template<typename _Arg1, typename _Arg2, typename _Result> inline pointer_to_binary_function<_Arg1, _Arg2, _Result> ptr_fun(_Result (*__x)(_Arg1, _Arg2)) { return pointer_to_binary_function<_Arg1, _Arg2, _Result>(__x); } /** @} */ template<typename _Tp> struct _Identity : public unary_function<_Tp,_Tp> { _Tp& operator()(_Tp& __x) const { return __x; } const _Tp& operator()(const _Tp& __x) const { return __x; } }; template<typename _Pair> struct _Select1st : public unary_function<_Pair, typename _Pair::first_type> { typename _Pair::first_type& operator()(_Pair& __x) const { return __x.first; } const typename _Pair::first_type& operator()(const _Pair& __x) const { return __x.first; } #if __cplusplus >= 201103L template<typename _Pair2> typename _Pair2::first_type& operator()(_Pair2& __x) const { return __x.first; } template<typename _Pair2> const typename _Pair2::first_type& operator()(const _Pair2& __x) const { return __x.first; } #endif }; template<typename _Pair> struct _Select2nd : public unary_function<_Pair, typename _Pair::second_type> { typename _Pair::second_type& operator()(_Pair& __x) const { return __x.second; } const typename _Pair::second_type& operator()(const _Pair& __x) const { return __x.second; } }; // 20.3.8 adaptors pointers members /** @defgroup memory_adaptors Adaptors for pointers to members * @ingroup functors * * There are a total of 8 = 2^3 function objects in this family. * (1) Member functions taking no arguments vs member functions taking * one argument. * (2) Call through pointer vs call through reference. * (3) Const vs non-const member function. * * All of this complexity is in the function objects themselves. You can * ignore it by using the helper function mem_fun and mem_fun_ref, * which create whichever type of adaptor is appropriate. * * @{ */ /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class mem_fun_t : public unary_function<_Tp*, _Ret> { public: explicit mem_fun_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) { } _Ret operator()(_Tp* __p) const { return (__p->*_M_f)(); } private: _Ret (_Tp::*_M_f)(); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class const_mem_fun_t : public unary_function<const _Tp*, _Ret> { public: explicit const_mem_fun_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) { } _Ret operator()(const _Tp* __p) const { return (__p->*_M_f)(); } private: _Ret (_Tp::*_M_f)() const; }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class mem_fun_ref_t : public unary_function<_Tp, _Ret> { public: explicit mem_fun_ref_t(_Ret (_Tp::*__pf)()) : _M_f(__pf) { } _Ret operator()(_Tp& __r) const { return (__r.*_M_f)(); } private: _Ret (_Tp::*_M_f)(); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp> class const_mem_fun_ref_t : public unary_function<_Tp, _Ret> { public: explicit const_mem_fun_ref_t(_Ret (_Tp::*__pf)() const) : _M_f(__pf) { } _Ret operator()(const _Tp& __r) const { return (__r.*_M_f)(); } private: _Ret (_Tp::*_M_f)() const; }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class mem_fun1_t : public binary_function<_Tp*, _Arg, _Ret> { public: explicit mem_fun1_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) { } _Ret operator()(_Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class const_mem_fun1_t : public binary_function<const _Tp*, _Arg, _Ret> { public: explicit const_mem_fun1_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) { } _Ret operator()(const _Tp* __p, _Arg __x) const { return (__p->*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg) const; }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> { public: explicit mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg)) : _M_f(__pf) { } _Ret operator()(_Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg); }; /// One of the @link memory_adaptors adaptors for member /// pointers@endlink. template<typename _Ret, typename _Tp, typename _Arg> class const_mem_fun1_ref_t : public binary_function<_Tp, _Arg, _Ret> { public: explicit const_mem_fun1_ref_t(_Ret (_Tp::*__pf)(_Arg) const) : _M_f(__pf) { } _Ret operator()(const _Tp& __r, _Arg __x) const { return (__r.*_M_f)(__x); } private: _Ret (_Tp::*_M_f)(_Arg) const; }; // Mem_fun adaptor helper functions. There are only two: // mem_fun and mem_fun_ref. template<typename _Ret, typename _Tp> inline mem_fun_t<_Ret, _Tp> mem_fun(_Ret (_Tp::*__f)()) { return mem_fun_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp> inline const_mem_fun_t<_Ret, _Tp> mem_fun(_Ret (_Tp::*__f)() const) { return const_mem_fun_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp> inline mem_fun_ref_t<_Ret, _Tp> mem_fun_ref(_Ret (_Tp::*__f)()) { return mem_fun_ref_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp> inline const_mem_fun_ref_t<_Ret, _Tp> mem_fun_ref(_Ret (_Tp::*__f)() const) { return const_mem_fun_ref_t<_Ret, _Tp>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline mem_fun1_t<_Ret, _Tp, _Arg> mem_fun(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline const_mem_fun1_t<_Ret, _Tp, _Arg> mem_fun(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_t<_Ret, _Tp, _Arg>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg)) { return mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } template<typename _Ret, typename _Tp, typename _Arg> inline const_mem_fun1_ref_t<_Ret, _Tp, _Arg> mem_fun_ref(_Ret (_Tp::*__f)(_Arg) const) { return const_mem_fun1_ref_t<_Ret, _Tp, _Arg>(__f); } /** @} */ _GLIBCXX_END_NAMESPACE_VERSION } // namespace #if (__cplusplus < 201103L) || _GLIBCXX_USE_DEPRECATED # include <backward/binders.h> #endif #endif /* _STL_FUNCTION_H */
10-24
OAM Engine Configuration The OAM engine configuration requires common infrastructure settings that affect all OAM flows. For each OAM flow, the application must configure the OAM Table attributes that define the flow behavior. This is achieved by setting the fields of the OAM Engine table. This table has 2K rules and it must be partitioned between Ingress and Egress OAM engines. The OAM engine table record is described in the CPSS_DXCH_OAM_ENTRY_STC structure. The flow configuration is described in details in OAM Engine Single Flow Configuration. The OAM engine detects various exceptions. The device also maintains special counters and indications of the exceptions. Exception handling configuration is described in OAM Exception – Configuration, Indications, Counters, and Recovery. Exception recovery is described in Exception Recovery. Using stage Parameter in OAM APIs Most of the CPSS APIs described in this section have a parameter called stage that defines if the API is applicable to either Ingress or Egress OAM processing. The Ingress and Egress processing is defined by the CPSS_DXCH_OAM_STAGE_TYPE_ENT type. To set the OAM processing to Ingress stage, use constant CPSS_DXCH_OAM_STAGE_TYPE_INGRESS_E. To set the OAM processing to Egress stage, use constant CPSS_DXCH_OAM_STAGE_TYPE_EGRESS_E. If the stage parameter is omitted, the API is applicable to both Ingress and Egress stages. OAM Engine Initialization To enable the Ingress or Egress OAM processing, call cpssDxChOamEnableSet. The OAM Engine table has 2K flow entries. The application may need to allocate continuous areas for OAM Ingress and Egress flows in the OAM table. To set the basic flow offset for each stage, call cpssDxChOamTableBaseFlowIdSet. All other OAM APIs rely on this setting for accessing the OAM table. Keepalive Functionality Configuration The OAM engine uses the keepalive daemon for monitoring the connectivity with a peer device. Each flow in the OAM table defines keepalive attributes. The built-in aging daemon applies them. To detect LOC, the daemon uses up to 8 configurable timers. Each timer is used to measure the time between successful keepalive message arrivals. The LOC timeout for a single flow is defined as the number of times the timer elapsed. A keepalive exception is raised if there was no packet for the configured time. Each timer can be set to a different period. Each flow can use any of the 8 timers. To enable keepalive detection on the device, call cpssDxChOamAgingDaemonEnableSet. Set the enable parameter to GT_TRUE to enable the aging daemon. If the daemon is enabled, the periodic keepalive check will be performed on entries according to the aging settings in the OAM Engine table. Otherwise, the Ingress or Egress keepalive check will be globally disabled. The device supports 8 different aging timers per stage to provide a greater granularity. To configure each one of the 8 aging timers, call cpssDxChOamAgingPeriodEntrySet. The timers are configured in units of 40 ns. The applicable range of time units is 0 to 0x3FFFFFFFF. Therefore, the maximal time that can be set equals to ~10 minutes. The timers are referenced in the OAM Table entry field agingPeriodIndex described in LOC Detection Configuration. An application may configure a keep-alive engine to process dropped keep-alive packets. There is a separate configuration for soft-dropped and hard-dropped packets. To enable processing of dropped packets, call cpssDxChOamKeepaliveForPacketCommandEnableSet. Reporting LOC Event Set OAM engine to report LOC events by calling cpssDxChOamAgingBitmapUpdateModeSet with mode set to CPSS_DXCH_OAM_AGING_BITMAP_UPDATE_MODE_ONLY_FAILURES_E. This ensures aging bitmap is updated only upon flow failure. Setting mode to CPSS_DXCH_OAM_AGING_BITMAP_UPDATE_MODE_ALL_E, allows updating aging bitmap to OK as well as to failure. Enabling Protection LOC The OAM Engine can trigger protection switching upon a LOC event. To enable a protection switching update, set the of CPSS_DXCH_OAM_ENTRY_STC, when calling cpssDxChOamEntrySet or cpssDxChOamPortGroupEntrySet. The protection switching configuration is described in Protection Switching. Note that the protection LOC update must be configured in the OAM Engine table at the same row as the row of the LOC table that implements the protection switch. Monitoring Payload In some cases, it is desired to validate the packet payload beyond verifying that the message had arrived with the correct header. The OAM engine provides the ability to monitor the packet payload for correctness. This is implemented by comparing the hashed value calculated for the monitored packet fields with the configured one. The OAM engine can optionally report the changes in the monitored packet data fields. To configure a continuous area of up to 12 bits that will be monitored by the hash mechanism, call cpssDxChOamHashBitSelectionSet. This setting will be used by the OAM engine as described in Packet Header Correctness Detection. OAM Table Related Configuration For a TCAM action to assign a flow ID to an OAM packet, the respective entry in the OAM table requires configuring using the cpssDxChOamEntrySet API. In addition, additional configurations are required for proper processing of OAM packets, as described below. Packet Command Profile Configuration The OAM engine uses the Packet Opcode table to apply commands and set CPU codes for packets trapped to the CPU. To access entries in the Opcode to Packet Command table is a lookup table, use the following two indexes: The 8-bit opcode from the CFM packet header The profile ID – The packetCommandProfile field of CPSS_DXCH_OAM_ENTRY_STC, set by the cpssDxChOamEntrySet API Call cpssDxChOamEntrySet to set the opcodeParsingEnable field of CPSS_DXCH_OAM_ENTRY_STC set to GT_TRUE, in order to enable access to the Opcode to Packet Command table. The contents of the table is a packet command of the CPSS_PACKET_CMD_ENT type, including CPSS_PACKET_CMD_LOOPBACK_E as a possible command. It is recommended to configure the table prior to enabling the OAM functionality. To configure the profile table, call cpssDxChOamOpcodeProfilePacketCommandEntrySet. If the packet command is drop or forward to CPU, cpssDxChOamOpcodeProfilePacketCommandEntrySet is also used to configure the CPU/DROP code to be sent to the CPU. Multicast packets can be automatically assigned (profile ID +1) for accessing the Packet Opcode table. In this way, an application can enable different handling for Multicast and Unicast flows. In order to enable a dedicated profile for Multicast traffic, use cpssDxChOamOpcodeProfileDedicatedMcProfileEnableSet. Dual-Ended Loss Measurement Command To define a packet command for Dual-Ended Loss Measurement packets, call cpssDxChOamDualEndedLmPacketCommandSet. The structure CPSS_PACKET_CMD_END describes the command types. CPU Code Configuration for Trapped Packets All trapped packets contain the CPU code that can be used by the application for further processing. The opcode is constructed dynamically for each packet from 3 configured values as follows: CPU_result_code=<OAM_CPU_Code_Base>+ (OAM_Table_Flow_Cpu_Code_Offset> << 2) + (Opcode_Packet_Command_Table_CPU_Code_Offset) where: OAM_CPU_Code_Base is the value configured by cpssDxChOamCpuCodeBaseSet. OAM Table_Cpu OAM_Table_Flow_Cpu_Code_Offset is the value configured for a specific flow in the OAM Engine table. For more details, see OAM Engine Single Flow Configuration. Opcode_Packet_Command_Table_CPU_Code_Offset is the value from the Opcode to Packet command table to be set by calling cpssDxChOamOpcodeProfilePacketCommandEntrySet. The available CPU code offset constants are defined by the CPSS_NET_RX_CPU_CODE_ENT enumeration type. Timestamp Configuration CPSS provides APIs that enable time stamping in OAM frames and configure the offset where the time stamp must be inserted. To enable time stamping parsing for the incoming frames, call cpssDxChOamTimeStampParsingEnableSet. To configure Ethertype to be inserted into outgoing DM frames, call cpssDxChOamTimeStampEtherTypeSet. Timestamping can be done anywhere within OAM packets using the PTP Timestamp table. To insert a timestamp: Call cpssDxChOamEntrySet to set the timestampEnable and oamPtpOffsetIndex fields of CPSS_DXCH_OAM_ENTRY_STC. If the packet is not DM, turn off (set to GT_FALSE) opcodeParsingEnable. Call cpssDxChPtpTsCfgTableSet to configure the entry of index oamPtpOffsetIndex from Step 1. Set the entry of type CPSS_DXCH_PTP_TS_CFG_ENTRY_STC to be used as a parameter of cpssDxChPtpTsCfgTableSet to: tsMode = CPSS_DXCH_PTP_TS_TIMESTAMPING_MODE_DO_ACTION_E Set tsAction of type CPSS_DXCH_PTP_TS_ACTION_ENT to the required timestamp type, for example CPSS_DXCH_PTP_TS_ACTION_ADD_INGRESS_TIME_E packetFormat = CPSS_DXCH_PTP_TS_PACKET_TYPE_Y1731_E ptpTransport = CPSS_DXCH_PTP_TRANSPORT_TYPE_ETHERNET_E Set L3 offset of timestamp insertion Packet to Opcode Table Usage Some OAM packets are processed as known types of OAM messages (LM, DM, CCM Keep Alive). OAM types with dedicated processing are listed in CPSS_DXCH_OAM_OPCODE_TYPE_ENT. Packet are classified by opcode-matching with predefined OAM opcode types listed in the Opcode table. Upon finding an opcode match, an internal OAM process (not an OAM Action) is triggered. Call cpssDxChOamOpcodeSet to set the table per stage and per OAM opcode type (keepalive message, LM, DM).it triggers The following figure illustrates the common format for all OAM PDUs. Figure 299: Common OAM PDU Format Set opcodeType to CPSS_DXCH_OAM_OPCODE_TYPE_LM_SINGLE_ENDED_E to configure opcode for the single-ended LM opcode. Set opcodeType to CPSS_DXCH_OAM_OPCODE_TYPE_LM_DUAL_ENDED_E to define an opcode for dual-ended loss measurement. Set opcodeType to CPSS_DXCH_OAM_OPCODE_TYPE_KEEPALIVE_E to define an opcode for keepalive monitoring. Note, that if the opcode does not match CPSS_DXCH_OAM_OPCODE_TYPE_DM_E, even though opcode parsing is enabled and timestampEnable is set, no timestamp is added to the packet. Each flow in the OAM table is configured to either attempt opcode matching or skip it. To enable OAM Engine matching of packet opcode to a configured one, call cpssDxChOamEntrySet, and set the field opcodeParsingEnable in CPSS_DXCH_OAM_ENTRY_STC. Loss Measurements Configuration – Destination Offset There is a special LM Offset table that contains a packet destination offset. The OAM engine accesses the LM Offset table to determine the offset in the packet and insert the LM counters data. This table is accessed according to the index configured in the OAM Engine table, as described in Loss Measurements (LM) Configuration. To configure the LM Offset table, call cpssDxChOamLmOffsetTableSet. The parameter entryIndex defines the table row. The parameter offset contains the offset value. IETF MPLS-TP OAM Support The OAM engine determines the packet command according to 8-bit opcode values retrieved from OAM packets. However, in the MPLS TP, the OAM is represented by a 16-bit MPLS Control Word value. The device provides a flexible way of mapping MPLS -TP Control Word to 8-bit opcode values used by the OAM engine. This is done by using 16 profiles. To map an MPLS Channel Type to a profile, call cpssDxChOamMplsCwChannelTypeProfileSet. To configure mapping profiles, call cpssDxChPclOamChannelTypeProfileToOpcodeMappingSet. OAM Exception – Configuration, Indications, Counters, and Recovery Exception Overview There are 7 OAM exceptions that may occur during OAM processing. Keepalive Aging Exception – Occurs when OAM flows age out and Loss of Continuity occurs. Excess Keepalive Exception – Occurs when an excess number of keepalive messages is received in one of the flows. RDI Status Exception – Occurs when an OAM message is received with an RDI value that is different than the current RDI status of the corresponding OAM Table entry. Tx Period Exception – Occurs when the transmission period of an OAM message differs from the configured transmission period in the corresponding OAM Table entry. Invalid Keepalive Exception – Occurs when the hash verification of a received OAM packet fails. MEG Level Exception – Occurs when the MEG Level of the received OAM message is lower than expected. Source Interface Exception – Occurs when the source interface of the OAM message is different from the one expected. The device also maintains a summary exception indication. It is set if any of the above exceptions occurs. The CPSS_DXCH_OAM_EXCEPTION_TYPE_ENT type must be used to define the exception type in any of the exception related APIs described in this section. Exception Action Configuration CPSS provides an API that defines the command to apply on a packet upon exception and the data to forward to the CPU if CPU TRAP was asserted upon exception. To bind a command and the CPU code to an exception, call cpssDxChOamExceptionConfigSet. The structure CPSS_DXCH_OAM_EXCEPTION_CONFIG_STC defines the command and CPU data for each exception. The commands to apply on the packet upon exception are listed by CPSS_PACKET_CMD_ENT. The codes to pass to the CPU are listed by CPSS_NET_RX_CPU_CODE_ENT. Exception Counters Access The device maintains counters for each exception type at the device level (cumulative counter for exceptions that occurred in all 2K flows). Call cpssDxChOamExceptionCounterGet to obtain the current value of the device level exception counter for the specified exception type. Note, the exception counters are not cleared on read, and wrap around upon reaching the maximal value (232-1). Counter types are listed by CPSS_DXCH_OAM_EXCEPTION_TYPE_ENT. Exception Recovery At times, exception state toggles from Fail to Pass. In such cases, it is possible to assign a pre-configured Recovery Packet Command and CPU/drop code to the packet that triggered the state change. This allows notifying the application of flow recovery by assigning a MIRROR command to the packet. To achieve that, call cpssDxChOamExceptionRecoveryConfigSet with exceptionCommandPtr (CPSS_DXCH_OAM_EXCEPTION_COMMAND_CONFIG_STC) set to the desired exception recovery configuration per the specified exception type and OAM direction/stage (ingress/egress). Exception Storm Suppression This section is applicable for Falcon family of devices CPSS allows suppressing exception storms for OAM exceptions, though it is possible to still assign command and CPU code (the latter, for packets marked as TO CPU) to the respective packets. To suppress exception storm for exceptions: Enable exception suppression for the desired exception type in the relevant OAM table entry (CPSS_DXCH_OAM_ENTRY_STC). The following fields are available: Keepalive aging – keepaliveAgingStormSuppressEnable Invalid keepalive hash – invalidHashKeepaliveStormSuppressEnable MEG level – megLevelStormSuppressEnable Source interface – sourceInterfaceStormSuppressEnable Tx period – txPeriodStormSuppressEnable NOTE: For explanation on each of these exception types, see OAM Exception – Configuration, Indications, Counters, and Recovery. Call cpssDxChOamExceptionSuppressConfigSet with exceptionCommandPtr (CPSS_DXCH_OAM_EXCEPTION_COMMAND_CONFIG_STC) set to the desired packet OAM handling configuration per the specified exception type and OAM direction/stage (ingress/egress). Exception Status Indication The device maintains 2 structures per each exception type—the device exception status vector, and flows exception status table. Device Exception Status Access The device exception status vector has 64 bits where each bit represents the cumulative exception status of 32 consecutive flows. For example, if bit 3 is set to 1, there is an exception in one of the flows, from flow 96 up to flow 127. To read the device exception status vector of all 2K flows, call cpssDxChOamExceptionGroupStatusGet. Set the exceptionType parameter to indicate the required exception type. Single-Flow Exception Status Access For each of the above exceptions, the device maintains an exception status indications table. The exception status indication table has 64 rows. Each row has 32 bits—one bit per OAM flow. When an exception occurs for flow i, the OAM engine sets bit i in the corresponding exception table row. Figure 300: Calculation of Flow ID with Exception To get the status of 32 flow exceptions, call cpssDxChOamExceptionStatusGet and provide the exception type and row index that contains the required flow exception. The cpssDxChOamExceptionGroupStatusGet API provides the row IDs to be used as inputs to cpssDxChOamExceptionStatusGet. In Falcon devices, obtain the exception status by calling cpssDxChOamPortGroupEntryGet. To detect which flow caused the exception, call cpssDxChOamExceptionGroupStatusGet. The indexes to set bits in the returned vector groupStatusArr must be used as input parameters to cpssDxChOamExceptionStatusGet. An example shown in the previous figure explains how to calculate the flow ID that caused the exception. OAM Engine Single Flow Configuration The OAM engine provides building blocks to implement any of the CFM protocols defined by the Ethernet OAM standards 802.1ag/Y.1731, MPLS OAM ITU-T Y.1711 standard, and others. The CFM supports 3 protocols with 3 message types: Linktrace Protocol with Linktrace Message (LTM) Continuity Check Protocol with Continuity Check Message (CCM) Loopback Protocol with Loopback Message LBM The standards also introduce the requirements for filtering CFM messages, Delay Measurements (DM) and Loss Measurements (LM) as well as for sending and detecting indications of local alarms. (RDI). The above requirements can be supported by configuring the entry in OAM Engine table. To configure an OAM Engine table entry, call cpssDxChOamEntrySet or cpssDxChOamPortGroupEntrySet. All the settings are configured through the CPSS_DXCH_OAM_ENTRY_STC structure field. The fields described in this section are assumed to be members of this structure. The OAM Engine table is configured for each OAM flow and consists of the following: OAM Packet Parsing MEG Level Filtering Configuration Source Interface Filtering Configuration Keepalive Monitoring Configuration Delay Measurement (DM) Configuration Loss Measurements (LM) Configuration OAM Packet Parsing Set opcodeParsingEnable to GT_TRUE to use the packet Opcode to determine the packet command. This field is typically enabled for OAM flows of the 802.1ag / Y.1731 / MPLS-TP OAM, and is typically disabled for flows of other OAM protocols, such as BFD or Y.1711. If set, the packet command is determined using the Opcode-to-packet-command table. For the LM and DM processing, set this field to apply the LM and DM actions only to packets with opcode that matches the configured opcodes. If opcodeParsingEnable is not set, the DM or LM action is applied to any packet that passes the TTI or PCL classification and is referred to OAM processing. For details on the DM processing, see Delay Measurement (DM) Configuration. For details on the LM processing, see Loss Measurements (LM) Configuration. MEG Level Filtering Configuration The IEEE 802.1ag l standard specifies that OAM messages of the level below the level configured must be dropped. In the following example, the device is configured to process OAM packets for portId =5, MEG level =3 and VID =10. Packets with MEG levels 0,1, and 2 must be dropped while packets with levels above 3 must be forwarded. Set the megLevelCheckEnable parameter to GT_TRUE to enable MEG filtering. Set megLevel = 3. CFM packets from any MEG level for port 0 and VID =10 will be classified for the OAM engine. The OAM engine will drop all packets below level 3 while the CFM frames above level 3 will be forwarded. The CFM packets of MEG level 3 will undergo OAM processing according to the Opcode to Packet command mapping table configuration. The MEG Level exception occurs when the MEG level of the received OAM message is lower than expected. Multiple MEG Level Filtering The same IEEE 802.1ag standard specifies that multiple MEG levels may be defined for a single interface. The following example explains how to configure 2 separate Maintenance Points (MP). There are 2 MP for the same service—one at level (3) and another one at Level (5). Port=0, VID=7, MEG Level=3 Port=0, VID=7, MEG Level=5 In this case, 2 separate OAM Table entries are created, one for each of these MPs: The first entry must not perform MEG filtering. megLevelCheckEnable = GT_FALSE The second entry – filtering enabled for MEG Level=5. megLevelCheckEnable = GT_TRUE megLevel = 5 Two corresponding TCAM rules are created for these flows: (either in the TTI or in the PCL) First rule – EtherType=CFM, Port=0, VID=7, MEG Level=3. Second rule (must appear after the first one) – EtherType=CFM, Port=0, VID=7, MEG Level=* The first rule binds the OAM flow with MEG Level=3 to the corresponding OAM entry. The second rule binds the OAM flow to the second OAM entry, resulting in a MEG Level filtering. The OAM packets with MEG level 3 will be matched by the first TCAM entry and will be processed by the OAM engine’s first rule. The other OAM packets with MEG levels other than 3 will be matched by the second TCAM rule, and will be processed by the second OAM entry. Thus, the following MEG Levels are dropped: 0, 1, 2, 4, while all packets in MEG Levels above 5 are forwarded. Source Interface Filtering Configuration Source interface filtering is defined in IEEE 802.1ag. The device can be configured to detect source interface violations. The Source Interface exception occurs when the source interface of the OAM message is different than the one configured, as explained further. If classification rules do not use the source interface as the classification parameter, the OAM frames may arrive from different interfaces. Set sourceInterfaceCheckEnable to enable source interface filtering. Set sourceInterface to define the filtering interface. To enable packet filtering from any port except for the configured one, set sourceInterfaceCheckMode to CPSS_DXCH_OAM_SOURCE_INTERFACE_CHECK_MODE_MATCH_E. Set sourceInterfaceCheckMode to CPSS_DXCH_OAM_SOURCE_INTERFACE_CHECK_MODE_NO_MATCH_E to raise an exception if an OAM packet arrives from the interface other than the one set in the sourceInterface field. Multiple Interface Filtering It is possible to configure filtering of multiple interfaces on the same device. Multiple MEPs can be defined within a single switch, with the same VID and MEG level, but with different interfaces. The following example shows how to configure processing of OAM packets from 2 different interfaces, while dropping OAM packets from any other interface. For example, 2 separate Down Maintenance Points (MP) may be defined as follows: ePort=0, VID=7, MEG Level=3 ePort=1, VID=7, MEG Level=3 In this case, 2 separate OAM Table entries are created, one for each of these MPs. First entry – the set source interface filtering is disabled. sourceInterfaceCheckEnable = GT_FALSE; Second entry – source interface filtering is enabled in the following way: sourceInterfaceCheckEnable = GT_TRUE; sourceInterface.portNum = 1; sourceInterfaceCheckMode = CPSS_DXCH_OAM_SOURCE_INTERFACE_CHECK_MODE_MATCH_E; Two corresponding TCAM rules are created for these flows (either in TTI or PCL). First rule – EtherType=CFM, ePort=0, VID=7. Second rule (must appear after the first one) – EtherType=CFM, ePort=*, VID=7. The first rule binds the OAM flow with ePort=0 to the corresponding OAM entry. The second rule binds the OAM flow to the second OAM entry, resulting in a source interface filtering. Thus, OAM packets with VID=7 from ePorts 0 or 1 are not dropped, while packets from other ports are dropped. Keepalive Monitoring Configuration Keepalive monitoring provides the following configurable functionalities: LOC Detection Configuration Packet Header Correctness Detection Excess Keep Alive Message Detection LOC Detection Configuration To define the keepalive timeout for the flow, set the agingPeriodIndex field to point to one of the 8 aging timers described in Keepalive Functionality Configuration. Set the agingThreshold field to configure the number of periods of the selected aging timer. LOC is detected if there is no CCM packet during the time period defined by agingThreshold. The Keepalive Aging exception occurs when an OAM flow ages out and LOC occurs. To configure the LOC timeout period for 100 ms using the aging timer of 1 ms, set agingThreshold =100. The Keepalive exception occurs if a message does not arrive within 100 ms. Packet Header Correctness Detection The device can be configured to detect the correctness of a packet header. Set the hashVerifyEnable field to enable detection. If enabled, the packet header is verified against the hash value that is set in the flowHash field. This field can be either configured by an API or can be dynamically set, according to the first OAM packet, by the device. To use the configured value, set the lockHashValueEnable field to GT_TRUE. Otherwise, the OAM engine will control this field. The packet header correctness check is based on monitoring a 12-bit hash value out of the 32-bit hash value computed by the hash generator. To select packet fields and a hash method, see Hash Modes and Mechanism. The configuration of a continuous area of up to 12 bits that will be monitored by the hash mechanism is described in Monitoring Payload. Excess Keep Alive Message Detection The OAM engine can be configured to detect excess keep alive messages. The excess keep alive detection algorithm causes the exception if for the configured detection time the expected number of keep alive messages is above the threshold. Set excessKeepaliveDetectionEnable to detect excess keepalive messages. To configure the detection time, set excessKeepalivePeriodThreshold to the number of aging timer periods and excessKeepaliveMessageThreshold to the minimal number of messages expected during the configured period. The Excess Keepalive exception occurs when an excess number of keepalive messages is received. Set the following fields to detect excess keepalive frames in 100 ms, using a minimal amount of messages (4), if the aging timer is configured to period of 1 ms. excessKeepalivePeriodThreshold =100; excessKeepaliveMessageThreshold =4; The OAM engine may be set to compare the period of received keepalive packets with the configured one. To enable this check, set the periodCheckEnable field and set the expected period in the keepaliveTxPeriod field. The Tx Period exception occurs when the transmission period of an OAM message differs from the configured transmission period in the corresponding OAM Table entry. RDI Check Configuration The OAM engine can be configured to compare the RDI field in the packet to the configured one in the OAM engine table. To enable this check, set the rdiCheckEnable field. The RDI check is performed only if the keepaliveAgingEnable field is set. The OAM Engine monitors the RDI bit that was extracted into UDB according to the profile. The expected location RDI must be set by calling cpssDxChPclOamRdiMatchingSet. The RDI Status exception occurs when an OAM message is received with an RDI value that is different than the current RDI status of the corresponding OAM Table entry. Delay Measurement (DM) Configuration The OAM Engine provides a convenient way to configure time stamping for implementing an accurate delay measurement functionality. The device maintains an internal Time of Day (ToD) counter that is used for time stamping. This ToD counter can be synchronized to a network Grandmaster clock using the Precision Time Protocol (PTP) or to a time server using the Network Time Protocol (NTP). For details on synchronizing the ToD, see Time Synchronization and Timestamping. The OAM engine uses the offset table defined in Time Synchronization and Timestamping to read the offset of the packet in which the time stamp must be inserted. The OAM Engine entry is configured with the index to the offset table. To enable time stamping in the OAM packets serviced by a flowId entry of the OAM engine, call cpssDxChOamEntrySet and set following fields: Set the opcodeParsingEnable field to GT_TRUE Set the timestampEnable field to GT_TRUE. Configure the offset of the packet where the time stamp is copied by setting the offsetIndex field to point to the offset table with the configured offset. The time stamping will be performed only for packets with an opcode matched to one of the 16 opcodes available in the DM Opcodes table. To configure 16 DM opcodes, call cpssDxChOamOpcodeSet. Set the opcodeType parameter to CPSS_DXCH_OAM_OPCODE_TYPE_DM_E and set 16 DM opcodes in opcodeValue. The opcodeIndex parameter defines the required index in the DM opcodes table. If opcodeParsingEnable is set to GT_FALSE, the timestamps are set to any packet classified to the OAM flow. Loss Measurements (LM) Configuration Loss Measurement (LM) is performed by reading billing and policy counters and inserting them into OAM frames. All the service counters are assigned using the TTI or PCL classification rules, as defined in a. The TTI, IPCL, or EPCL engine rules must be set to bound the traffic to counters. Only a green conforming counter out of 3 billing counters is used for LM. For more details on configuring counters in the TTI engine, see TTI Rules and Actions. For more details on configuring counters in a PCL lookup, see Policy Action. An OAM Engine Table rule defines where to insert LM counters into a frame. The OAM engine maintains a table that allows setting LM values into a different offset depending on the packet opcode. The LM configuration is explained in detail further in this section. The OAM packets are identified and classified into flows in the TTI (see TTI Rules and Actions). The relevant rule action must have the following fields set: oamProcessEnable + flowId – Bind the packet to a specific entry in the OAM table. bindToPolicer – This field must be enabled in the action entry if LM counting is enabled for this flow. policerIndex – Specifies the index of the LM counting entry when Bind To Policer Counter is set. To bind the Policer counter to the OAM, call cpssDxChPclRuleSetas defined in Policy Action. To define LM counting, call cpssDxChOamEntrySet and set following fields in structure CPSS_DXCH_OAM_ENTRY_ST: To enable counting of OAM packets in LM, set lmCountingMode = CPSS_DXCH_OAM_LM_COUNTING_MODE_ENABLE_E. To insert an Egress counter into the packet as defined in the LM table, set the lmCounterCaptureEnable to GT_TRUE. To define an offset for inserting the LM data, set offsetIndex to point to the LM Offset table (see Loss Measurements Configuration – Destination Offset). CPU Code Offset Configuration To configure the value to be added to the CPU code value for packets trapped or mirrored to the CPU, configure the cpuCodeOffset field.能否提取到cpssDxChOamEntrySet适用于哪些机型,AC5调用哪个接口
最新发布
12-06
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值