1 # Copyright (c) 2021 Intel 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 """Loadbalancer util library."""
16 from ipaddress import ip_address
17 from socket import htonl
19 from resources.libraries.python.topology import NodeType, Topology
20 from resources.libraries.python.PapiExecutor import PapiSocketExecutor
23 class LoadBalancerUtil:
24 """Basic Loadbalancer parameter configuration."""
27 def vpp_lb_conf(node, **kwargs):
28 """Config global parameters for loadbalancer.
30 :param node: Node where the interface is.
31 :param kwargs: Optional key-value arguments:
33 ip4_src_addr: IPv4 address to be used as source for IPv4 traffic.
35 ip6_src_addr: IPv6 address to be used as source for IPv6 traffic.
37 flow_timeout: Time in seconds after which, if no packet is received
38 for a given flow, the flow is removed from the
39 established flow table. (int)
40 buckets_per_core: Number of buckets *per worker thread* in the
41 established flow table (int)
46 :raises ValueError: If the node has an unknown node type.
48 if node[u"type"] == NodeType.DUT:
49 ip4_src_addr = ip_address(
50 kwargs.pop(u"ip4_src_addr", u"255.255.255.255")
52 ip6_src_addr = ip_address(
54 u"ip6_src_addr", u"ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff"
57 flow_timeout = kwargs.pop(u"flow_timeout", 40)
58 sticky_buckets_per_core = kwargs.pop(u"buckets_per_core", 1024)
61 err_msg = f"Failed to set lb conf on host {node[u'host']}"
63 ip4_src_address=str(ip4_src_addr),
64 ip6_src_address=str(ip6_src_addr),
65 sticky_buckets_per_core=sticky_buckets_per_core,
66 flow_timeout=flow_timeout
69 with PapiSocketExecutor(node) as papi_exec:
70 papi_exec.add(cmd, **args).get_reply(err_msg)
73 f"Node {node[u'host']} has unknown NodeType: '{node[u'type']}'"
77 def vpp_lb_add_del_vip(node, **kwargs):
78 """Config vip for loadbalancer.
80 :param node: Node where the interface is.
81 :param kwargs: Optional key-value arguments:
83 vip_addr: IPv4 address to be used as source for IPv4 traffic. (str)
84 protocol: tcp or udp. (int)
85 port: destination port. (int)
86 encap: encap is ip4 GRE(0) or ip6 (1GRE) or L3DSR(2) or NAT4(3) or
88 dscp: dscp bit corresponding to VIP
90 target_port: Pod's port corresponding to specific service
91 node_port: Node's port
92 new_len: Size of the new connections flow table used
94 is_del: 1 if the VIP should be removed otherwise 0.
99 :raises ValueError: If the node has an unknown node type.
101 if node[u"type"] == NodeType.DUT:
102 vip_addr = kwargs.pop(u"vip_addr", "0.0.0.0")
103 protocol = kwargs.pop(u"protocol", 255)
104 port = kwargs.pop(u"port", 0)
105 encap = kwargs.pop(u"encap", 0)
106 dscp = kwargs.pop(u"dscp", 0)
107 srv_type = kwargs.pop(u"srv_type", 0)
108 target_port = kwargs.pop(u"target_port", 0)
109 node_port = kwargs.pop(u"node_port", 0)
110 new_len = kwargs.pop(u"new_len", 1024)
111 is_del = kwargs.pop(u"is_del", 0)
113 cmd = u"lb_add_del_vip"
114 err_msg = f"Failed to add vip on host {node[u'host']}"
116 vip_addr = ip_address(vip_addr).packed
120 u"address": {u"un": {u"ip4": vip_addr}, u"af": 0}
127 target_port=target_port,
129 new_flows_table_length=int(new_len),
133 with PapiSocketExecutor(node) as papi_exec:
134 papi_exec.add(cmd, **args).get_reply(err_msg)
137 f"Node {node[u'host']} has unknown NodeType: '{node[u'type']}'"
141 def vpp_lb_add_del_as(node, **kwargs):
142 """Config AS for Loadbalancer.
144 :param node: Node where the interface is.
145 :param kwargs: Optional key-value arguments:
147 vip_addr: IPv4 address to be used as source for IPv4 traffic. (str)
148 protocol: tcp or udp. (int)
149 port: destination port. (int)
150 as_addr: The application server address. (str)
151 is_del: 1 if the VIP should be removed otherwise 0. (int)
152 is_flush: 1 if the sessions related to this AS should be flushed
158 :raises ValueError: If the node has an unknown node type.
160 if node[u"type"] == NodeType.DUT:
161 cmd = u"lb_add_del_as"
162 err_msg = f"Failed to add lb as on host {node[u'host']}"
164 vip_addr = kwargs.pop(u"vip_addr", "0.0.0.0")
165 protocol = kwargs.pop(u"protocol", 255)
166 port = kwargs.pop(u"port", 0)
167 as_addr = kwargs.pop(u"as_addr", u"0.0.0.0")
168 is_del = kwargs.pop(u"is_del", 0)
169 is_flush = kwargs.pop(u"is_flush", 0)
171 vip_addr = ip_address(vip_addr).packed
172 as_addr = ip_address(as_addr).packed
177 u"address": {u"un": {u"ip4": vip_addr}, u"af": 0}
181 as_address={u"un": {u"ip4": as_addr}, u"af": 0},
186 with PapiSocketExecutor(node) as papi_exec:
187 papi_exec.add(cmd, **args).get_reply(err_msg)
190 f"Node {node[u'host']} has unknown NodeType: '{node[u'type']}'"
194 def vpp_lb_add_del_intf_nat4(node, **kwargs):
195 """Enable/disable NAT4 feature on the interface.
197 :param node: Node where the interface is.
198 :param kwargs: Optional key-value arguments:
200 is_add: true if add, false if delete. (bool)
201 interface: software index of the interface. (int)
206 :raises ValueError: If the node has an unknown node type.
208 if node[u"type"] == NodeType.DUT:
209 cmd = u"lb_add_del_intf_nat4"
210 err_msg = f"Failed to add interface nat4 on host {node[u'host']}"
212 is_add = kwargs.pop(u"is_add", True)
213 interface = kwargs.pop(u"interface", 0)
214 sw_if_index = Topology.get_interface_sw_index(node, interface)
217 sw_if_index=sw_if_index
220 with PapiSocketExecutor(node) as papi_exec:
221 papi_exec.add(cmd, **args).get_reply(err_msg)
224 f"Node {node[u'host']} has unknown NodeType: '{node[u'type']}'"