1 # Copyright (c) 2019 Cisco and/or its affiliates.
2 # Licensed under the Apache License, Version 2.0 (the "License");
3 # you may not use this file except in compliance with the License.
4 # You may obtain a copy of the License at:
6 # http://www.apache.org/licenses/LICENSE-2.0
8 # Unless required by applicable law or agreed to in writing, software
9 # distributed under the License is distributed on an "AS IS" BASIS,
10 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 # See the License for the specific language governing permissions and
12 # limitations under the License.
14 """Policer utilities library."""
16 from enum import IntEnum
18 from resources.libraries.python.Constants import Constants
19 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
20 from resources.libraries.python.topology import Topology
23 class PolicerRateType(IntEnum):
24 """Policer rate types."""
30 class PolicerRoundType(IntEnum):
31 """Policer round types."""
38 class PolicerType(IntEnum):
41 TYPE_1R3C_RFC_2697 = 1
42 TYPE_2R3C_RFC_2698 = 2
43 TYPE_2R3C_RFC_4115 = 3
44 TYPE_2R3C_RFC_MEF5CF1 = 4
48 class PolicerAction(IntEnum):
55 class PolicerPreColor(IntEnum):
56 """Policer Pre-color."""
63 """DSCP for mark-and-transmit action."""
84 class Policer(object):
85 """Policer utilities."""
87 # pylint: disable=too-many-arguments, too-many-locals
89 def policer_set_configuration(
90 node, policer_name, cir, eir, cbs, ebs, rate_type, round_type,
91 policer_type, conform_action_type, exceed_action_type,
92 violate_action_type, color_aware, is_add=True, conform_dscp=None,
93 exceed_dscp=None, violate_dscp=None):
94 """Configure policer on VPP node.
96 :param node: VPP node.
97 :param policer_name: Name of the policer.
98 :param cir: Committed information rate.
99 :param eir: Excess (or Peak) information rate.
100 :param cbs: Committed burst size.
101 :param ebs: Excess (or Peak) burst size.
102 :param rate_type: Rate type.
103 :param round_type: Round type.
104 :param policer_type: Policer algorithm.
105 :param conform_action_type: Conform action type.
106 :param exceed_action_type: Exceed action type.
107 :param violate_action_type: Violate action type.
108 :param color_aware: Color-blind (cb) or color-aware (ca).
109 :param is_add: Add policer if True, else delete.
110 :param conform_dscp: DSCP for conform mark_and_transmit action.
111 :param exceed_dscp: DSCP for exceed mark_and_transmit action.
112 :param violate_dscp: DSCP for vilate mark_and_transmit action.
114 :type policer_name: str
120 :type round_type: str
121 :type policer_type: str
122 :type conform_action_type: str
123 :type exceed_action_type: str
124 :type violate_action_type: str
125 :type color_aware: str
127 :type conform_dscp: str
128 :type exceed_dscp: str
129 :type violate_dscp: str
131 cmd = 'policer_add_del'
134 name=str(policer_name),
139 rate_type=getattr(PolicerRateType, rate_type.upper()).value,
141 PolicerRoundType, 'ROUND_TO_{rt}'.format(
142 rt=round_type.upper())).value,
143 type=getattr(PolicerType, 'TYPE_{pt}'.format(
144 pt=policer_type.upper())).value,
145 conform_action_type=getattr(
146 PolicerAction, conform_action_type.upper()).value,
147 conform_dscp=getattr(DSCP, 'D_{dscp}'.format(
148 dscp=conform_dscp.upper())).value
150 conform_action_type.upper() == PolicerAction.MARK_AND_TRANSMIT.name
152 exceed_action_type=getattr(
153 PolicerAction, exceed_action_type.upper()).value,
154 exceed_dscp=getattr(DSCP, 'D_{dscp}'.format(
155 dscp=exceed_dscp.upper())).value
157 exceed_action_type.upper() == PolicerAction.MARK_AND_TRANSMIT.name
159 violate_action_type=getattr(
160 PolicerAction, violate_action_type.upper()).value,
161 violate_dscp=getattr(DSCP, 'D_{dscp}'.format(
162 dscp=violate_dscp.upper())).value
164 violate_action_type.upper() == PolicerAction.MARK_AND_TRANSMIT.name
166 color_aware=1 if color_aware == "'ca'" else 0
168 err_msg = 'Failed to configure policer {pn} on host {host}'.format(
169 pn=policer_name, host=node['host'])
171 with PapiSocketExecutor(node) as papi_exec:
172 reply = papi_exec.add(cmd, **args).get_reply(err_msg)
174 return reply['policer_index']
177 def policer_classify_set_interface(
178 node, interface, ip4_table_index=Constants.BITWISE_NON_ZERO,
179 ip6_table_index=Constants.BITWISE_NON_ZERO,
180 l2_table_index=Constants.BITWISE_NON_ZERO, is_add=1):
181 """Set/unset policer classify interface.
183 :param node: VPP node.
184 :param interface: Interface name or sw_if_index to set/unset policer
186 :param ip4_table_index: IP4 classify table index (~0 to skip).
188 :param ip6_table_index: IP6 classify table index (~0 to skip).
190 :param l2_table_index: L2 classify table index (~0 to skip).
192 :param is_add: Set if non-zero, else unset.
194 :type interface: str or int
195 :type ip4_table_index: int
196 :type ip6_table_index: int
197 :type l2_table_index: int
199 if isinstance(interface, basestring):
200 sw_if_index = Topology.get_interface_sw_index(node, interface)
202 sw_if_index = interface
204 cmd = 'policer_classify_set_interface'
208 sw_if_index=sw_if_index,
209 ip4_table_index=int(ip4_table_index),
210 ip6_table_index=int(ip6_table_index),
211 l2_table_index=int(l2_table_index)
213 err_msg = 'Failed to set/unset policer classify interface {ifc} ' \
214 'on host {host}'.format(ifc=interface, host=node['host'])
216 with PapiSocketExecutor(node) as papi_exec:
217 papi_exec.add(cmd, **args).get_reply(err_msg)
220 def policer_classify_get_precolor(precolor):
221 """Return policer pre-color numeric value.
223 :param precolor: Policer pre-color name.
225 :returns: Policer pre-color numeric value.
228 return getattr(PolicerPreColor, precolor.upper()).value
231 def get_dscp_num_value(dscp):
232 """Return DSCP numeric value.
234 :param dscp: DSCP name.
236 :returns: DSCP numeric value.
239 return getattr(DSCP, 'D_{dscp}'.format(dscp=dscp.upper())).value