import random
from framework import VppTestCase, VppTestRunner, running_extended_tests
+
+import scapy.compat
from scapy.layers.inet import IP, TCP, UDP, ICMP
from scapy.layers.inet import IPerror, TCPerror, UDPerror, ICMPerror
from scapy.layers.inet6 import IPv6, ICMPv6EchoRequest, ICMPv6EchoReply, \
IntField("sequence_number", 1),
IntField("thread_index", 0),
PacketListField("events", [], Event,
- count_from=lambda pkt:pkt.count)]
+ count_from=lambda pkt: pkt.count)]
class MethodHolder(VppTestCase):
interfaces = self.vapi.nat44_interface_addr_dump()
for intf in interfaces:
- self.vapi.nat44_add_interface_addr(intf.sw_if_index,
- twice_nat=intf.twice_nat,
- is_add=0)
+ self.vapi.nat44_add_del_interface_addr(intf.sw_if_index,
+ twice_nat=intf.twice_nat,
+ is_add=0)
- self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
- domain_id=self.ipfix_domain_id)
+ self.vapi.nat_ipfix_enable_disable(enable=0,
+ src_port=self.ipfix_src_port,
+ domain_id=self.ipfix_domain_id)
self.ipfix_src_port = 4739
self.ipfix_domain_id = 1
pref_n[13] = ip4_n[1]
pref_n[14] = ip4_n[2]
pref_n[15] = ip4_n[3]
- return socket.inet_ntop(socket.AF_INET6, ''.join(pref_n))
+ packed_pref_n = b''.join([scapy.compat.chb(x) for x in pref_n])
+ return socket.inet_ntop(socket.AF_INET6, packed_pref_n)
def extract_ip4(self, ip6, plen):
"""
p = (IP(src=src_if.remote_ip4, dst=dst) /
TCP(sport=sport, dport=dport) /
Raw(data))
- p = p.__class__(str(p))
- chksum = p['TCP'].chksum
+ p = p.__class__(scapy.compat.raw(p))
+ chksum = p[TCP].chksum
proto_header = TCP(sport=sport, dport=dport, chksum=chksum)
elif proto == IP_PROTOS.udp:
proto_header = UDP(sport=sport, dport=dport)
self.assertEqual(6, len(data))
for record in data:
# natEvent
- self.assertIn(ord(record[230]), [4, 5])
- if ord(record[230]) == 4:
+ self.assertIn(scapy.compat.orb(record[230]), [4, 5])
+ if scapy.compat.orb(record[230]) == 4:
nat44_ses_create_num += 1
else:
nat44_ses_delete_num += 1
# ingressVRFID
self.assertEqual(struct.pack("!I", 0), record[234])
# protocolIdentifier/sourceTransportPort/postNAPTSourceTransportPort
- if IP_PROTOS.icmp == ord(record[4]):
+ if IP_PROTOS.icmp == scapy.compat.orb(record[4]):
self.assertEqual(struct.pack("!H", self.icmp_id_in), record[7])
self.assertEqual(struct.pack("!H", self.icmp_id_out),
record[227])
- elif IP_PROTOS.tcp == ord(record[4]):
+ elif IP_PROTOS.tcp == scapy.compat.orb(record[4]):
self.assertEqual(struct.pack("!H", self.tcp_port_in),
record[7])
self.assertEqual(struct.pack("!H", self.tcp_port_out),
record[227])
- elif IP_PROTOS.udp == ord(record[4]):
+ elif IP_PROTOS.udp == scapy.compat.orb(record[4]):
self.assertEqual(struct.pack("!H", self.udp_port_in),
record[7])
self.assertEqual(struct.pack("!H", self.udp_port_out),
self.assertEqual(1, len(data))
record = data[0]
# natEvent
- self.assertEqual(ord(record[230]), 3)
+ self.assertEqual(scapy.compat.orb(record[230]), 3)
# natPoolID
self.assertEqual(struct.pack("!I", 0), record[283])
self.assertEqual(1, len(data))
record = data[0]
# natEvent
- self.assertEqual(ord(record[230]), 13)
+ self.assertEqual(scapy.compat.orb(record[230]), 13)
# natQuotaExceededEvent
self.assertEqual(struct.pack("I", 1), record[466])
# maxSessionEntries
self.assertEqual(1, len(data))
record = data[0]
# natEvent
- self.assertEqual(ord(record[230]), 13)
+ self.assertEqual(scapy.compat.orb(record[230]), 13)
# natQuotaExceededEvent
self.assertEqual(struct.pack("I", 2), record[466])
# maxBIBEntries
self.assertEqual(1, len(data))
record = data[0]
# natEvent
- self.assertEqual(ord(record[230]), 13)
+ self.assertEqual(scapy.compat.orb(record[230]), 13)
# natQuotaExceededEvent
self.assertEqual(struct.pack("I", 5), record[466])
# maxFragmentsPendingReassembly
self.assertEqual(1, len(data))
record = data[0]
# natEvent
- self.assertEqual(ord(record[230]), 13)
+ self.assertEqual(scapy.compat.orb(record[230]), 13)
# natQuotaExceededEvent
self.assertEqual(struct.pack("I", 5), record[466])
# maxFragmentsPendingReassembly
record = data[0]
# natEvent
if is_create:
- self.assertEqual(ord(record[230]), 10)
+ self.assertEqual(scapy.compat.orb(record[230]), 10)
else:
- self.assertEqual(ord(record[230]), 11)
+ self.assertEqual(scapy.compat.orb(record[230]), 11)
# sourceIPv6Address
self.assertEqual(src_addr, record[27])
# postNATSourceIPv4Address
self.assertEqual(self.nat_addr_n, record[225])
# protocolIdentifier
- self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
+ self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
# ingressVRFID
self.assertEqual(struct.pack("!I", 0), record[234])
# sourceTransportPort
record = data[0]
# natEvent
if is_create:
- self.assertEqual(ord(record[230]), 6)
+ self.assertEqual(scapy.compat.orb(record[230]), 6)
else:
- self.assertEqual(ord(record[230]), 7)
+ self.assertEqual(scapy.compat.orb(record[230]), 7)
# sourceIPv6Address
self.assertEqual(src_addr, record[27])
# destinationIPv6Address
self.assertEqual(socket.inet_pton(socket.AF_INET, dst_addr),
record[226])
# protocolIdentifier
- self.assertEqual(IP_PROTOS.tcp, ord(record[4]))
+ self.assertEqual(IP_PROTOS.tcp, scapy.compat.orb(record[4]))
# ingressVRFID
self.assertEqual(struct.pack("!I", 0), record[234])
# sourceTransportPort
self.assertEqual(1, len(data))
record = data[0]
# natEvent
- self.assertEqual(ord(record[230]), 13)
+ self.assertEqual(scapy.compat.orb(record[230]), 13)
# natQuotaExceededEvent
self.assertEqual(struct.pack("I", 3), record[466])
# maxEntriesPerUser
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
- data = "A" * 4 + "B" * 16 + "C" * 3
+ data = b"A" * 4 + b"B" * 16 + b"C" * 3
else:
- data = "A" * 16 + "B" * 16 + "C" * 3
+ data = b"A" * 16 + b"B" * 16 + b"C" * 3
self.port_in = random.randint(1025, 65535)
reass = self.vapi.nat_reass_dump()
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
- data = "A" * 4 + "B" * 16 + "C" * 3
+ data = b"A" * 4 + b"B" * 16 + b"C" * 3
else:
- data = "A" * 16 + "B" * 16 + "C" * 3
+ data = b"A" * 16 + b"B" * 16 + b"C" * 3
self.port_in = random.randint(1025, 65535)
for i in range(2):
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
- data = "A" * 4 + "B" * 16 + "C" * 3
+ data = b"A" * 4 + b"B" * 16 + b"C" * 3
else:
- data = "A" * 16 + "B" * 16 + "C" * 3
+ data = b"A" * 16 + b"B" * 16 + b"C" * 3
# send packet from host to server
pkts = self.create_stream_frag(self.pg0,
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
- data = "A" * 4 + "B" * 16 + "C" * 3
+ data = b"A" * 4 + b"B" * 16 + b"C" * 3
else:
- data = "A" * 16 + "B" * 16 + "C" * 3
+ data = b"A" * 16 + b"B" * 16 + b"C" * 3
self.port_in = random.randint(1025, 65535)
for i in range(2):
layer = self.proto2layer(proto)
if proto == IP_PROTOS.tcp:
- data = "A" * 4 + "B" * 16 + "C" * 3
+ data = b"A" * 4 + b"B" * 16 + b"C" * 3
else:
- data = "A" * 16 + "B" * 16 + "C" * 3
+ data = b"A" * 16 + b"B" * 16 + b"C" * 3
self.port_in = random.randint(1025, 65535)
for i in range(2):
cls.pg1.configure_ipv4_neighbors()
cls.overlapping_interfaces = list(list(cls.pg_interfaces[4:7]))
- cls.vapi.ip_table_add_del(10, is_add=1)
- cls.vapi.ip_table_add_del(20, is_add=1)
+ cls.vapi.ip_table_add_del(is_add=1, table_id=10)
+ cls.vapi.ip_table_add_del(is_add=1, table_id=20)
cls.pg4._local_ip4 = "172.16.255.1"
cls.pg4._local_ip4n = socket.inet_pton(socket.AF_INET, i.local_ip4)
cls.pg9.generate_remote_hosts(2)
cls.pg9.config_ip4()
ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
- cls.vapi.sw_interface_add_del_address(cls.pg9.sw_if_index,
- ip_addr_n,
- 24)
+ cls.vapi.sw_interface_add_del_address(
+ sw_if_index=cls.pg9.sw_if_index, address=ip_addr_n,
+ address_length=24)
cls.pg9.admin_up()
cls.pg9.resolve_arp()
cls.pg9._remote_hosts[1]._ip4 = cls.pg9._remote_hosts[0]._ip4
def test_interface_addr(self):
""" Acquire NAT44 addresses from interface """
- self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
+ self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
# no address in NAT pool
adresses = self.vapi.nat44_address_dump()
""" Static mapping with addresses from interface """
tag = "testTAG"
- self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
+ self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
self.nat44_add_static_mapping(
'1.2.3.4',
external_sw_if_index=self.pg7.sw_if_index,
""" Identity NAT with addresses from interface """
port = 53053
- self.vapi.nat44_add_interface_addr(self.pg7.sw_if_index)
+ self.vapi.nat44_add_del_interface_addr(self.pg7.sw_if_index)
self.vapi.nat44_add_del_identity_mapping(
sw_if_index=self.pg7.sw_if_index,
port=port,
path_mtu=512,
template_interval=10,
collector_port=colector_port)
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
pkts = self.create_stream_in(self.pg0, self.pg1)
self.pg0.add_stream(pkts)
src_address=self.pg3.local_ip4n,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
src_address=self.pg3.local_ip4n,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
p = (Ether(dst=self.pg0.local_mac, src=self.pg0.remote_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
self.pg0.unconfig_ip4()
self.pg1.unconfig_ip4()
- self.vapi.ip_table_add_del(vrf_id1, is_add=1)
- self.vapi.ip_table_add_del(vrf_id2, is_add=1)
+ self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
+ self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
self.pg0.set_table_ip4(vrf_id1)
self.pg1.set_table_ip4(vrf_id2)
self.pg0.config_ip4()
self.pg1.config_ip4()
self.pg0.resolve_arp()
self.pg1.resolve_arp()
- self.vapi.ip_table_add_del(vrf_id1, is_add=0)
- self.vapi.ip_table_add_del(vrf_id2, is_add=0)
+ self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id1)
+ self.vapi.ip_table_add_del(is_add=0, table_id=vrf_id2)
def test_vrf_feature_independent(self):
""" NAT44 tenant VRF independent address pool mode """
def test_frag_forwarding(self):
""" NAT44 forwarding fragment test """
- self.vapi.nat44_add_interface_addr(self.pg1.sw_if_index)
+ self.vapi.nat44_add_del_interface_addr(self.pg1.sw_if_index)
self.vapi.nat44_interface_add_del_feature(self.pg0.sw_if_index)
self.vapi.nat44_interface_add_del_feature(self.pg1.sw_if_index,
is_inside=0)
self.vapi.nat44_forwarding_enable_disable(1)
- data = "A" * 16 + "B" * 16 + "C" * 3
+ data = b"A" * 16 + b"B" * 16 + b"C" * 3
pkts = self.create_stream_frag(self.pg1,
self.pg0.remote_ip4,
4789,
src_address=self.pg3.local_ip4n,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
- data = "A" * 4 + "B" * 16 + "C" * 3
+ data = b"A" * 4 + b"B" * 16 + b"C" * 3
self.tcp_port_in = random.randint(1025, 65535)
pkts = self.create_stream_frag(self.pg0,
self.pg1.remote_ip4,
self.pg1.unconfig_ip4()
self.pg2.unconfig_ip4()
- self.vapi.ip_table_add_del(vrf_id1, is_add=1)
- self.vapi.ip_table_add_del(vrf_id2, is_add=1)
+ self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id1)
+ self.vapi.ip_table_add_del(is_add=1, table_id=vrf_id2)
self.pg1.set_table_ip4(vrf_id1)
self.pg2.set_table_ip4(vrf_id2)
self.pg1.config_ip4()
cls.pg4.generate_remote_hosts(2)
cls.pg4.config_ip4()
ip_addr_n = socket.inet_pton(socket.AF_INET, "10.0.0.1")
- cls.vapi.sw_interface_add_del_address(cls.pg4.sw_if_index,
- ip_addr_n,
- 24)
+ cls.vapi.sw_interface_add_del_address(
+ sw_if_index=cls.pg4.sw_if_index, address=ip_addr_n,
+ address_length=24)
cls.pg4.admin_up()
cls.pg4.resolve_arp()
cls.pg4._remote_hosts[1]._ip4 = cls.pg4._remote_hosts[0]._ip4
cls.pg4.resolve_arp()
zero_ip4n = socket.inet_pton(socket.AF_INET, "0.0.0.0")
- cls.vapi.ip_table_add_del(1, is_add=1)
+ cls.vapi.ip_table_add_del(is_add=1, table_id=1)
cls.pg5._local_ip4 = "10.1.1.1"
cls.pg5._local_ip4n = socket.inet_pton(socket.AF_INET,
port_in1 = port_in
port_in2 = port_in
else:
- port_in1 = port_in+1
- port_in2 = port_in+2
+ port_in1 = port_in + 1
+ port_in2 = port_in + 2
port_out = 80
eh_port_out = 4567
def test_twice_nat_interface_addr(self):
""" Acquire twice NAT44 addresses from interface """
- self.vapi.nat44_add_interface_addr(self.pg3.sw_if_index, twice_nat=1)
+ self.vapi.nat44_add_del_interface_addr(self.pg3.sw_if_index,
+ twice_nat=1)
# no address in NAT pool
adresses = self.vapi.nat44_address_dump()
local_port, external_port, vrf_id=1,
proto=IP_PROTOS.tcp, out2in_only=1)
self.nat44_add_static_mapping(
- self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
- local_port=local_port, vrf_id=0, external_port=external_port,
- proto=IP_PROTOS.tcp, out2in_only=1)
+ self.pg0.remote_ip4, external_sw_if_index=self.pg0.sw_if_index,
+ local_port=local_port, vrf_id=0, external_port=external_port,
+ proto=IP_PROTOS.tcp, out2in_only=1)
# from client to service (both VRF1)
p = (Ether(src=self.pg6.remote_mac, dst=self.pg6.local_mac) /
self.pg_start()
capture = self.pg1.get_capture(len(pkts))
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
IP(src=self.pg0.remote_ip4, dst=self.pg1.remote_ip4) /
cls.pg1.config_ip6()
cls.pg1.resolve_ndp()
- cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00'*16,
+ cls.vapi.ip_add_del_route(is_ipv6=True, dst_address='\x00' * 16,
dst_address_length=0,
next_hop_address=cls.pg1.remote_ip6n,
next_hop_sw_if_index=cls.pg1.sw_if_index)
src_address=self.pg2.local_ip4n,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix()
+ self.vapi.nat_ipfix_enable_disable()
pkts = []
for port in range(1025, 2025):
"""
Clear deterministic NAT configuration.
"""
- self.vapi.nat_ipfix(enable=0)
+ self.vapi.nat_ipfix_enable_disable(enable=0)
self.vapi.nat_set_timeouts()
deterministic_mappings = self.vapi.nat_det_map_dump()
for dsm in deterministic_mappings:
cls.ip6_interfaces.append(cls.pg_interfaces[2])
cls.ip4_interfaces = list(cls.pg_interfaces[1:2])
- cls.vapi.ip_table_add_del(cls.vrf1_id, is_add=1, is_ipv6=1)
+ cls.vapi.ip_table_add_del(is_ipv6=1, is_add=1,
+ table_id=cls.vrf1_id)
cls.pg_interfaces[2].set_table_ip6(cls.vrf1_id)
self.assertTrue(pg1_found)
features = self.vapi.cli("show interface features pg0")
- self.assertNotEqual(features.find('nat64-in2out'), -1)
+ self.assertIn('nat64-in2out', features)
features = self.vapi.cli("show interface features pg1")
- self.assertNotEqual(features.find('nat64-out2in'), -1)
+ self.assertIn('nat64-out2in', features)
self.vapi.nat64_add_del_interface(self.pg0.sw_if_index, is_add=0)
self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_add=0)
reass_n_start = len(reass)
# in2out
- data = 'a' * 200
+ data = b'a' * 200
pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
self.tcp_port_in, 20, data)
self.pg0.add_stream(pkts)
self.assertEqual(data, p[Raw].load)
# out2in
- data = "A" * 4 + "b" * 16 + "C" * 3
+ data = b"A" * 4 + b"b" * 16 + b"C" * 3
pkts = self.create_stream_frag(self.pg1,
self.nat_addr,
20,
self.vapi.nat64_add_del_interface(self.pg1.sw_if_index, is_inside=0)
# in2out
- data = 'a' * 200
+ data = b'a' * 200
pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
self.tcp_port_in, 20, data)
pkts.reverse()
self.assertEqual(data, p[Raw].load)
# out2in
- data = "A" * 4 + "B" * 16 + "C" * 3
+ data = b"A" * 4 + b"B" * 16 + b"C" * 3
pkts = self.create_stream_frag(self.pg1,
self.nat_addr,
20,
def test_interface_addr(self):
""" Acquire NAT64 pool addresses from interface """
- self.vapi.nat64_add_interface_addr(self.pg4.sw_if_index)
+ self.vapi.nat64_add_del_interface_addr(self.pg4.sw_if_index)
# no address in NAT64 pool
adresses = self.vapi.nat44_address_dump()
src_address=self.pg3.local_ip4n,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
IPv6(src=src, dst=remote_host_ip6) /
src_address=self.pg3.local_ip4n,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
- data = 'a' * 200
+ data = b'a' * 200
pkts = self.create_stream_frag_ip6(self.pg0, self.pg1.remote_ip4,
self.tcp_port_in, 20, data)
pkts.reverse()
src_address=self.pg3.local_ip4n,
path_mtu=512,
template_interval=10)
- self.vapi.nat_ipfix(domain_id=self.ipfix_domain_id,
- src_port=self.ipfix_src_port)
+ self.vapi.nat_ipfix_enable_disable(domain_id=self.ipfix_domain_id,
+ src_port=self.ipfix_src_port)
# Create
p = (Ether(src=self.pg0.remote_mac, dst=self.pg0.local_mac) /
for p in capture:
if p.haslayer(Data):
data = ipfix.decode_data_set(p.getlayer(Set))
- if ord(data[0][230]) == 10:
+ if scapy.compat.orb(data[0][230]) == 10:
self.verify_ipfix_bib(data, 1, self.pg0.remote_ip6n)
- elif ord(data[0][230]) == 6:
+ elif scapy.compat.orb(data[0][230]) == 6:
self.verify_ipfix_nat64_ses(data,
1,
self.pg0.remote_ip6n,
self.ipfix_domain_id)
if p.haslayer(Data):
data = ipfix.decode_data_set(p.getlayer(Set))
- if ord(data[0][230]) == 11:
+ if scapy.compat.orb(data[0][230]) == 11:
self.verify_ipfix_bib(data, 0, self.pg0.remote_ip6n)
- elif ord(data[0][230]) == 7:
+ elif scapy.compat.orb(data[0][230]) == 7:
self.verify_ipfix_nat64_ses(data,
0,
self.pg0.remote_ip6n,
"""
Clear NAT64 configuration.
"""
- self.vapi.nat_ipfix(enable=0, src_port=self.ipfix_src_port,
- domain_id=self.ipfix_domain_id)
+ self.vapi.nat_ipfix_enable_disable(enable=0,
+ src_port=self.ipfix_src_port,
+ domain_id=self.ipfix_domain_id)
self.ipfix_src_port = 4739
self.ipfix_domain_id = 1