diff options
-rw-r--r-- | MAINTAINERS | 5 | ||||
-rw-r--r-- | src/vat/api_format.c | 48 | ||||
-rw-r--r-- | src/vnet/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/vnet/policer/policer.api | 70 | ||||
-rw-r--r-- | src/vnet/policer/policer_api.c | 31 | ||||
-rw-r--r-- | src/vnet/policer/policer_types.api | 62 | ||||
-rw-r--r-- | src/vpp/api/custom_dump.c | 6 | ||||
-rw-r--r-- | test/test_ip4.py | 8 | ||||
-rw-r--r-- | test/test_ip6.py | 8 | ||||
-rw-r--r-- | test/vpp_papi_provider.py | 37 | ||||
-rw-r--r-- | test/vpp_policer.py | 69 |
11 files changed, 225 insertions, 124 deletions
diff --git a/MAINTAINERS b/MAINTAINERS index d0abdffd7ad..08b8bc48bee 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -83,6 +83,11 @@ I: classify M: Dave Barach <dave@barachs.net> F: src/vnet/classify +VNET Policer +I: policer +M: N/A +F: src/vnet/policer/ + VNET Device Drivers I: devices Y: src/vnet/devices/af_packet/FEATURE.yaml diff --git a/src/vat/api_format.c b/src/vat/api_format.c index a98e2ed873d..a18eb91dae5 100644 --- a/src/vat/api_format.c +++ b/src/vat/api_format.c @@ -4555,18 +4555,18 @@ vl_api_policer_details_t_handler (vl_api_policer_details_t * mp) vat_main_t *vam = &vat_main; u8 *conform_dscp_str, *exceed_dscp_str, *violate_dscp_str; - if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) - conform_dscp_str = format (0, "%U", format_dscp, mp->conform_dscp); + if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT) + conform_dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp); else conform_dscp_str = format (0, ""); - if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) - exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp); + if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT) + exceed_dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp); else exceed_dscp_str = format (0, ""); - if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) - violate_dscp_str = format (0, "%U", format_dscp, mp->violate_dscp); + if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT) + violate_dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp); else violate_dscp_str = format (0, ""); @@ -4593,11 +4593,11 @@ vl_api_policer_details_t_handler (vl_api_policer_details_t * mp) ntohl (mp->extended_limit), ntohl (mp->extended_bucket), clib_net_to_host_u64 (mp->last_update_time), - format_policer_action_type, mp->conform_action_type, + format_policer_action_type, mp->conform_action.type, conform_dscp_str, - format_policer_action_type, mp->exceed_action_type, + format_policer_action_type, mp->exceed_action.type, exceed_dscp_str, - format_policer_action_type, mp->violate_action_type, + format_policer_action_type, mp->violate_action.type, violate_dscp_str); vec_free (conform_dscp_str); @@ -4618,11 +4618,11 @@ static void vl_api_policer_details_t_handler_json format (0, "%U", format_policer_round_type, mp->round_type); type_str = format (0, "%U", format_policer_type, mp->type); conform_action_str = format (0, "%U", format_policer_action_type, - mp->conform_action_type); + mp->conform_action.type); exceed_action_str = format (0, "%U", format_policer_action_type, - mp->exceed_action_type); + mp->exceed_action.type); violate_action_str = format (0, "%U", format_policer_action_type, - mp->violate_action_type); + mp->violate_action.type); if (VAT_JSON_ARRAY != vam->json_tree.type) { @@ -4658,24 +4658,24 @@ static void vl_api_policer_details_t_handler_json ntohl (mp->last_update_time)); vat_json_object_add_string_copy (node, "conform_action", conform_action_str); - if (mp->conform_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) + if (mp->conform_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT) { - u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_dscp); + u8 *dscp_str = format (0, "%U", format_dscp, mp->conform_action.dscp); vat_json_object_add_string_copy (node, "conform_dscp", dscp_str); vec_free (dscp_str); } vat_json_object_add_string_copy (node, "exceed_action", exceed_action_str); - if (mp->exceed_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) + if (mp->exceed_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT) { - u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_dscp); + u8 *dscp_str = format (0, "%U", format_dscp, mp->exceed_action.dscp); vat_json_object_add_string_copy (node, "exceed_dscp", dscp_str); vec_free (dscp_str); } vat_json_object_add_string_copy (node, "violate_action", violate_action_str); - if (mp->violate_action_type == SSE2_QOS_ACTION_MARK_AND_TRANSMIT) + if (mp->violate_action.type == SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT) { - u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_dscp); + u8 *dscp_str = format (0, "%U", format_dscp, mp->violate_action.dscp); vat_json_object_add_string_copy (node, "violate_dscp", dscp_str); vec_free (dscp_str); } @@ -17382,12 +17382,12 @@ api_policer_add_del (vat_main_t * vam) mp->rate_type = rate_type; mp->round_type = round_type; mp->type = type; - mp->conform_action_type = conform_action.action_type; - mp->conform_dscp = conform_action.dscp; - mp->exceed_action_type = exceed_action.action_type; - mp->exceed_dscp = exceed_action.dscp; - mp->violate_action_type = violate_action.action_type; - mp->violate_dscp = violate_action.dscp; + mp->conform_action.type = conform_action.action_type; + mp->conform_action.dscp = conform_action.dscp; + mp->exceed_action.type = exceed_action.action_type; + mp->exceed_action.dscp = exceed_action.dscp; + mp->violate_action.type = violate_action.action_type; + mp->violate_action.dscp = violate_action.dscp; mp->color_aware = color_aware; S (mp); diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 5ea5f16ab84..0ae1b0a8328 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -98,7 +98,10 @@ list(APPEND VNET_HEADERS policer/xlate.h ) -list(APPEND VNET_API_FILES policer/policer.api) +list(APPEND VNET_API_FILES + policer/policer.api + policer/policer_types.api +) ############################################################################## # Cop - junk filter diff --git a/src/vnet/policer/policer.api b/src/vnet/policer/policer.api index 8ca0ffbc791..946cc357b80 100644 --- a/src/vnet/policer/policer.api +++ b/src/vnet/policer/policer.api @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015-2016 Cisco and/or its affiliates. + * Copyright (c) 2015-2020 Cisco and/or its affiliates. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at: @@ -13,7 +13,9 @@ * limitations under the License. */ -option version = "1.0.0"; +option version = "2.0.0"; + +import "vnet/policer/policer_types.api"; /** \brief Add/del policer @param client_index - opaque cookie to identify the sender @@ -28,34 +30,28 @@ option version = "1.0.0"; @param round_type - rounding type @param type - policer algorithm @param color_aware - 0=color-blind, 1=color-aware - @param conform_action_type - conform action type - @param conform_dscp - DSCP for conform mar-and-transmit action - @param exceed_action_type - exceed action type - @param exceed_dscp - DSCP for exceed mar-and-transmit action - @param violate_action_type - violate action type - @param violate_dscp - DSCP for violate mar-and-transmit action + @param conform_action - conform action + @param exceed_action - exceed action type + @param violate_action - violate action type */ define policer_add_del { u32 client_index; u32 context; - u8 is_add; - u8 name[64]; + bool is_add; + string name[64]; u32 cir; u32 eir; u64 cb; u64 eb; - u8 rate_type; - u8 round_type; - u8 type; - u8 color_aware; - u8 conform_action_type; - u8 conform_dscp; - u8 exceed_action_type; - u8 exceed_dscp; - u8 violate_action_type; - u8 violate_dscp; + vl_api_sse2_qos_rate_type_t rate_type; + vl_api_sse2_qos_round_type_t round_type; + vl_api_sse2_qos_policer_type_t type; + bool color_aware; + vl_api_sse2_qos_action_t conform_action; + vl_api_sse2_qos_action_t exceed_action; + vl_api_sse2_qos_action_t violate_action; }; /** \brief Add/del policer response @@ -81,8 +77,8 @@ define policer_dump u32 client_index; u32 context; - u8 match_name_valid; - u8 match_name[64]; + bool match_name_valid; + string match_name[64]; }; /** \brief Policer operational state response. @@ -95,12 +91,9 @@ define policer_dump @param rate_type - rate type @param round_type - rounding type @param type - policer algorithm - @param conform_action_type - conform action type - @param conform_dscp - DSCP for conform mar-and-transmit action - @param exceed_action_type - exceed action type - @param exceed_dscp - DSCP for exceed mar-and-transmit action - @param violate_action_type - violate action type - @param violate_dscp - DSCP for violate mar-and-transmit action + @param conform_action - conform action + @param exceed_action - exceed action + @param violate_action - violate action @param single_rate - 1 = single rate policer, 0 = two rate policer @param color_aware - for hierarchical policing @param scale - power-of-2 shift amount for lower rates @@ -116,22 +109,19 @@ define policer_details { u32 context; - u8 name[64]; + string name[64]; u32 cir; u32 eir; u64 cb; u64 eb; - u8 rate_type; - u8 round_type; - u8 type; - u8 conform_action_type; - u8 conform_dscp; - u8 exceed_action_type; - u8 exceed_dscp; - u8 violate_action_type; - u8 violate_dscp; - u8 single_rate; - u8 color_aware; + vl_api_sse2_qos_rate_type_t rate_type; + vl_api_sse2_qos_round_type_t round_type; + vl_api_sse2_qos_policer_type_t type; + vl_api_sse2_qos_action_t conform_action; + vl_api_sse2_qos_action_t exceed_action; + vl_api_sse2_qos_action_t violate_action; + bool single_rate; + bool color_aware; u32 scale; u32 cir_tokens_per_period; u32 pir_tokens_per_period; diff --git a/src/vnet/policer/policer_api.c b/src/vnet/policer/policer_api.c index ae57a9359ea..b543a3c2e0e 100644 --- a/src/vnet/policer/policer_api.c +++ b/src/vnet/policer/policer_api.c @@ -68,12 +68,16 @@ vl_api_policer_add_del_t_handler (vl_api_policer_add_del_t * mp) cfg.rb.kbps.eir_kbps = ntohl (mp->eir); cfg.rb.kbps.cb_bytes = clib_net_to_host_u64 (mp->cb); cfg.rb.kbps.eb_bytes = clib_net_to_host_u64 (mp->eb); - cfg.conform_action.action_type = mp->conform_action_type; - cfg.conform_action.dscp = mp->conform_dscp; - cfg.exceed_action.action_type = mp->exceed_action_type; - cfg.exceed_action.dscp = mp->exceed_dscp; - cfg.violate_action.action_type = mp->violate_action_type; - cfg.violate_action.dscp = mp->violate_dscp; + cfg.conform_action.action_type = + (sse2_qos_action_type_en) mp->conform_action.type; + cfg.conform_action.dscp = mp->conform_action.dscp; + cfg.exceed_action.action_type = + (sse2_qos_action_type_en) mp->exceed_action.type; + cfg.exceed_action.dscp = mp->exceed_action.dscp; + cfg.violate_action.action_type = + (sse2_qos_action_type_en) mp->violate_action.type; + cfg.violate_action.dscp = mp->violate_action.dscp; + cfg.color_aware = mp->color_aware; error = policer_add_del (vm, name, &cfg, &policer_index, mp->is_add); @@ -111,12 +115,15 @@ send_policer_details (u8 * name, mp->rate_type = config->rate_type; mp->round_type = config->rnd_type; mp->type = config->rfc; - mp->conform_action_type = config->conform_action.action_type; - mp->conform_dscp = config->conform_action.dscp; - mp->exceed_action_type = config->exceed_action.action_type; - mp->exceed_dscp = config->exceed_action.dscp; - mp->violate_action_type = config->violate_action.action_type; - mp->violate_dscp = config->violate_action.dscp; + mp->conform_action.type = + (vl_api_sse2_qos_action_type_t) config->conform_action.action_type; + mp->conform_action.dscp = config->conform_action.dscp; + mp->exceed_action.type = + (vl_api_sse2_qos_action_type_t) config->exceed_action.action_type; + mp->exceed_action.dscp = config->exceed_action.dscp; + mp->violate_action.type = + (vl_api_sse2_qos_action_type_t) config->violate_action.action_type; + mp->violate_action.dscp = config->violate_action.dscp; mp->single_rate = templ->single_rate ? 1 : 0; mp->color_aware = templ->color_aware ? 1 : 0; mp->scale = htonl (templ->scale); diff --git a/src/vnet/policer/policer_types.api b/src/vnet/policer/policer_types.api new file mode 100644 index 00000000000..903bb603d78 --- /dev/null +++ b/src/vnet/policer/policer_types.api @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2020 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +enum sse2_qos_rate_type : u8 +{ + SSE2_QOS_RATE_API_KBPS = 0, + SSE2_QOS_RATE_API_PPS, + SSE2_QOS_RATE_API_INVALID, +}; + +enum sse2_qos_round_type : u8 +{ + SSE2_QOS_ROUND_API_TO_CLOSEST = 0, + SSE2_QOS_ROUND_API_TO_UP, + SSE2_QOS_ROUND_API_TO_DOWN, + SSE2_QOS_ROUND_API_INVALID, +}; + +enum sse2_qos_policer_type : u8 +{ + SSE2_QOS_POLICER_TYPE_API_1R2C = 0, + SSE2_QOS_POLICER_TYPE_API_1R3C_RFC_2697 = 1, + SSE2_QOS_POLICER_TYPE_API_2R3C_RFC_2698 = 2, + SSE2_QOS_POLICER_TYPE_API_2R3C_RFC_4115 = 3, + SSE2_QOS_POLICER_TYPE_API_2R3C_RFC_MEF5CF1 = 4, + SSE2_QOS_POLICER_TYPE_API_MAX, +}; + +enum sse2_qos_action_type : u8 +{ + SSE2_QOS_ACTION_API_DROP = 0, + SSE2_QOS_ACTION_API_TRANSMIT, + SSE2_QOS_ACTION_API_MARK_AND_TRANSMIT, +}; + +/** \brief SSE2 QOS action + @param conform_action_type - conform action type + @param conform_dscp - DSCP for conform mark-and-transmit action +*/ +typedef sse2_qos_action +{ + vl_api_sse2_qos_action_type_t type; + u8 dscp; +}; + +/* + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ diff --git a/src/vpp/api/custom_dump.c b/src/vpp/api/custom_dump.c index a4e04ebeaf2..1cc2aa64c28 100644 --- a/src/vpp/api/custom_dump.c +++ b/src/vpp/api/custom_dump.c @@ -2189,11 +2189,11 @@ static void *vl_api_policer_add_del_t_print } s = format (s, "conform_action %U ", format_policer_action, - mp->conform_action_type, mp->conform_dscp); + mp->conform_action.type, mp->conform_action.dscp); s = format (s, "exceed_action %U ", format_policer_action, - mp->exceed_action_type, mp->exceed_dscp); + mp->exceed_action.type, mp->exceed_action.dscp); s = format (s, "violate_action %U ", format_policer_action, - mp->violate_action_type, mp->violate_dscp); + mp->violate_action.type, mp->violate_action.dscp); if (mp->color_aware) s = format (s, "color-aware "); diff --git a/test/test_ip4.py b/test/test_ip4.py index 46a8306815b..87059c7361b 100644 --- a/test/test_ip4.py +++ b/test/test_ip4.py @@ -21,6 +21,7 @@ from vpp_sub_interface import VppSubInterface, VppDot1QSubint, VppDot1ADSubint from vpp_papi import VppEnum from vpp_neighbor import VppNeighbor from vpp_lo_interface import VppLoInterface +from vpp_policer import VppPolicer NUM_PKTS = 67 @@ -1390,8 +1391,8 @@ class TestIPPunt(VppTestCase): # # add a policer # - policer = self.vapi.policer_add_del(b"ip4-punt", 400, 0, 10, 0, - rate_type=1) + policer = VppPolicer(self, "ip4-punt", 400, 0, 10, 0, rate_type=1) + policer.add_vpp_config() self.vapi.ip_punt_police(policer.policer_index) self.vapi.cli("clear trace") @@ -1411,8 +1412,7 @@ class TestIPPunt(VppTestCase): # remove the policer. back to full rx # self.vapi.ip_punt_police(policer.policer_index, is_add=0) - self.vapi.policer_add_del(b"ip4-punt", 400, 0, 10, 0, - rate_type=1, is_add=0) + policer.remove_vpp_config() self.send_and_expect(self.pg0, pkts, self.pg1) # diff --git a/test/test_ip6.py b/test/test_ip6.py index f4b9ef8c647..b27cfdb4fed 100644 --- a/test/test_ip6.py +++ b/test/test_ip6.py @@ -28,6 +28,7 @@ from vpp_ip_route import VppIpRoute, VppRoutePath, find_route, VppIpMRoute, \ from vpp_neighbor import find_nbr, VppNeighbor from vpp_pg_interface import is_ipv6_misc from vpp_sub_interface import VppSubInterface, VppDot1QSubint +from vpp_policer import VppPolicer from ipaddress import IPv6Network, IPv6Address AF_INET6 = socket.AF_INET6 @@ -2118,8 +2119,8 @@ class TestIP6Punt(VppTestCase): # # add a policer # - policer = self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0, - rate_type=1) + policer = VppPolicer(self, "ip6-punt", 400, 0, 10, 0, rate_type=1) + policer.add_vpp_config() self.vapi.ip_punt_police(policer.policer_index, is_ip6=1) self.vapi.cli("clear trace") @@ -2139,8 +2140,7 @@ class TestIP6Punt(VppTestCase): # remove the policer. back to full rx # self.vapi.ip_punt_police(policer.policer_index, is_add=0, is_ip6=1) - self.vapi.policer_add_del(b"ip6-punt", 400, 0, 10, 0, - rate_type=1, is_add=0) + policer.remove_vpp_config() self.send_and_expect(self.pg0, pkts, self.pg1) # diff --git a/test/vpp_papi_provider.py b/test/vpp_papi_provider.py index 832fd8ff93c..52ce492adbd 100644 --- a/test/vpp_papi_provider.py +++ b/test/vpp_papi_provider.py @@ -96,7 +96,7 @@ defaultmapping = { 'ip6_table_index': 4294967295, 'l2_table_index': 4294967295, }, 'pppoe_add_del_session': {'is_add': 1, }, - 'policer_add_del': {'is_add': 1, 'conform_action_type': 1, }, + 'policer_add_del': {'is_add': 1, 'conform_action': {'type': 1}, }, 'proxy_arp_add_del': {'is_add': 1, }, 'proxy_arp_intfc_enable_disable': {'is_enable': 1, }, 'set_ip_flow_hash': {'src': 1, 'dst': 1, 'sport': 1, 'dport': 1, @@ -1166,41 +1166,6 @@ class VppPapiProvider(object): return self.api( self.papi.macip_acl_dump, {'acl_index': acl_index}) - def policer_add_del(self, - name, - cir, - eir, - cb, - eb, - is_add=1, - rate_type=0, - round_type=0, - ptype=0, - color_aware=0, - conform_action_type=1, - conform_dscp=0, - exceed_action_type=0, - exceed_dscp=0, - violate_action_type=0, - violate_dscp=0): - return self.api(self.papi.policer_add_del, - {'name': name, - 'cir': cir, - 'eir': eir, - 'cb': cb, - 'eb': eb, - 'is_add': is_add, - 'rate_type': rate_type, - 'round_type': round_type, - 'type': ptype, - 'color_aware': color_aware, - 'conform_action_type': conform_action_type, - 'conform_dscp': conform_dscp, - 'exceed_action_type': exceed_action_type, - 'exceed_dscp': exceed_dscp, - 'violate_action_type': violate_action_type, - 'violate_dscp': violate_dscp}) - def ip_punt_police(self, policer_index, is_ip6=0, diff --git a/test/vpp_policer.py b/test/vpp_policer.py new file mode 100644 index 00000000000..49d11859646 --- /dev/null +++ b/test/vpp_policer.py @@ -0,0 +1,69 @@ +from vpp_object import VppObject +from vpp_ip import INVALID_INDEX + + +class PolicerAction(): + """ sse2 qos action """ + + def __init__(self, type, dscp): + self.type = type + self.dscp = dscp + + def encode(self): + return {'type': self.type, 'dscp': self.dscp} + + +class VppPolicer(VppObject): + """ Policer """ + + def __init__(self, test, name, cir, eir, commited_burst, excess_burst, + rate_type=0, round_type=0, type=0, color_aware=False, + conform_action=PolicerAction(1, 0), + exceed_action=PolicerAction(0, 0), + violate_action=PolicerAction(0, 0)): + self._test = test + self.name = name + self.cir = cir + self.eir = eir + self.commited_burst = commited_burst + self.excess_burst = excess_burst + self.rate_type = rate_type + self.round_type = round_type + self.type = type + self.color_aware = color_aware + self.conform_action = conform_action + self.exceed_action = exceed_action + self.violate_action = violate_action + self._policer_index = INVALID_INDEX + + @property + def policer_index(self): + return self._policer_index + + def add_vpp_config(self): + r = self._test.vapi.policer_add_del( + name=self.name, cir=self.cir, + eir=self.eir, cb=self.commited_burst, eb=self.excess_burst, + rate_type=self.rate_type, round_type=self.round_type, + type=self.type, color_aware=self.color_aware, + conform_action=self.conform_action.encode(), + exceed_action=self.exceed_action.encode(), + violate_action=self.violate_action.encode()) + self._test.registry.register(self, self._test.logger) + self._policer_index = r.policer_index + return self + + def remove_vpp_config(self): + self._test.vapi.policer_add_del(is_add=False, name=self.name) + self._policer_index = INVALID_INDEX + + def query_vpp_config(self): + dump = self._test.vapi.policer_dump( + match_name_valid=True, match_name=self.name) + for policer in dump: + if policer.name == self.name: + return True + return False + + def object_id(self): + return ("policer-%s" % (self.name)) |