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 """NAT utilities library."""
16 from pprint import pformat
17 from socket import AF_INET, inet_pton
19 from enum import IntEnum
21 from robot.api import logger
23 from resources.libraries.python.InterfaceUtil import InterfaceUtil
24 from resources.libraries.python.PapiExecutor import PapiExecutor
27 class NATConfigFlags(IntEnum):
28 """Common NAT plugin APIs"""
30 NAT_IS_TWICE_NAT = 0x01
31 NAT_IS_SELF_TWICE_NAT = 0x02
32 NAT_IS_OUT2IN_ONLY = 0x04
33 NAT_IS_ADDR_ONLY = 0x08
37 NAT_IS_EXT_HOST_VALID = 0x80
40 class NATUtil(object):
41 """This class defines the methods to set NAT."""
47 def set_nat44_interfaces(node, int_in, int_out):
48 """Set inside and outside interfaces for NAT44.
50 :param node: DUT node.
51 :param int_in: Inside interface.
52 :param int_out: Outside interface.
58 cmd = 'nat44_interface_add_del_feature'
60 int_in_idx = InterfaceUtil.get_sw_if_index(node, int_in)
61 err_msg = 'Failed to set inside interface {int} for NAT44 on host ' \
62 '{host}'.format(int=int_in, host=node['host'])
64 sw_if_index=int_in_idx,
66 flags=getattr(NATConfigFlags, "NAT_IS_INSIDE").value
68 with PapiExecutor(node) as papi_exec:
69 papi_exec.add(cmd, **args_in).get_replies(err_msg).\
70 verify_reply(err_msg=err_msg)
72 int_out_idx = InterfaceUtil.get_sw_if_index(node, int_out)
73 err_msg = 'Failed to set outside interface {int} for NAT44 on host ' \
74 '{host}'.format(int=int_out, host=node['host'])
76 sw_if_index=int_out_idx,
78 flags=getattr(NATConfigFlags, "NAT_IS_OUTSIDE").value
80 with PapiExecutor(node) as papi_exec:
81 papi_exec.add(cmd, **args_in).get_replies(err_msg). \
82 verify_reply(err_msg=err_msg)
85 def set_nat44_deterministic(node, ip_in, subnet_in, ip_out, subnet_out):
86 """Set deterministic behaviour of NAT44.
88 :param node: DUT node.
89 :param ip_in: Inside IP.
90 :param subnet_in: Inside IP subnet.
91 :param ip_out: Outside IP.
92 :param subnet_out: Outside IP subnet.
95 :type subnet_in: str or int
97 :type subnet_out: str or int
100 cmd = 'nat_det_add_del_map'
101 err_msg = 'Failed to set deterministic behaviour of NAT on host ' \
102 '{host}'.format(host=node['host'])
105 in_addr=inet_pton(AF_INET, str(ip_in)),
106 in_plen=int(subnet_in),
107 out_addr=inet_pton(AF_INET, str(ip_out)),
108 out_plen=int(subnet_out)
110 with PapiExecutor(node) as papi_exec:
111 papi_exec.add(cmd, **args_in).get_replies(err_msg). \
112 verify_reply(err_msg=err_msg)
116 """Show the NAT configuration and data.
122 nat44_interface_addr_dump
124 nat44_static_mapping_dump
127 nat44_user_session_dump
130 :param node: DUT node.
134 cmd = 'nat_show_config'
135 err_msg = 'Failed to get NAT configuration on host {host}'.\
136 format(host=node['host'])
137 with PapiExecutor(node) as papi_exec:
138 data = papi_exec.add(cmd).get_replies(err_msg).\
139 verify_reply(err_msg=err_msg)
140 logger.debug("NAT Configuration:\n{data}".format(data=pformat(data)))
144 "nat44_interface_addr_dump",
145 "nat44_address_dump",
146 "nat44_static_mapping_dump",
148 "nat44_interface_dump",
149 "nat44_user_session_dump",
152 PapiExecutor.dump_and_log(node, cmds)