summaryrefslogtreecommitdiffstats
path: root/src/plugins/acl/bihash_40_8.h
blob: ba3dfbeaaf072e8441b9833b313454adfd8bf5b8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
/*
 * Copyright (c) 2015 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.
 */
#undef BIHASH_TYPE

#define BIHASH_TYPE _40_8
#define BIHASH_KVP_PER_PAGE 4

#ifndef __included_bihash_40_8_h__
#define __included_bihash_40_8_h__

#include <vppinfra/heap.h>
#include <vppinfra/format.h>
#include <vppinfra/pool.h>
#include <vppinfra/xxhash.h>

typedef struct
{
  u64 key[5];
  u64 value;
} clib_bihash_kv_40_8_t;

static inline int
clib_bihash_is_free_40_8 (const clib_bihash_kv_40_8_t * v)
{
  /* Free values are memset to 0xff, check a bit... */
  if (v->key[0] == ~0ULL && v->value == ~0ULL)
    return 1;
  return 0;
}

static inline u64
clib_bihash_hash_40_8 (const clib_bihash_kv_40_8_t * v)
{
#if __SSE4_2__
  u32 value = 0;
  value = _mm_crc32_u64 (value, v->key[0]);
  value = _mm_crc32_u64 (value, v->key[1]);
  value = _mm_crc32_u64 (value, v->key[2]);
  value = _mm_crc32_u64 (value, v->key[3]);
  value = _mm_crc32_u64 (value, v->key[4]);
  return value;
#else
  u64 tmp = v->key[0] ^ v->key[1] ^ v->key[2] ^ v->key[3] ^ v->key[4];
  return clib_xxhash (tmp);
#endif
}

static inline u8 *
format_bihash_kvp_40_8 (u8 * s, va_list * args)
{
  clib_bihash_kv_40_8_t *v = va_arg (*args, clib_bihash_kv_40_8_t *);

  s = format (s, "key %llu %llu %llu %llu %llu value %llu",
	      v->key[0], v->key[1], v->key[2], v->key[3], v->key[4],
	      v->value);
  return s;
}

static inline int
clib_bihash_key_compare_40_8 (const u64 * a, const u64 * b)
{
  return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2]) | (a[3] ^ b[3]) |
	  (a[4] ^ b[4])) == 0;
}

#undef __included_bihash_template_h__
#include <vppinfra/bihash_template.h>

#endif /* __included_bihash_40_8_h__ */

/*
 * fd.io coding-style-patch-verification: ON
 *
 * Local Variables:
 * eval: (c-set-style "gnu")
 * End:
 */
return False def set_unnumbered(self, ip_sw_if_index, is_add=True): res = self._test.vapi.sw_interface_set_unnumbered( self.east, ip_sw_if_index, is_add) res = self._test.vapi.sw_interface_set_unnumbered( self.west, ip_sw_if_index, is_add) class TestPipe(VppTestCase): """ Pipes """ def setUp(self): super(TestPipe, self).setUp() self.create_pg_interfaces(range(4)) for i in self.pg_interfaces: i.admin_up() def tearDown(self): for i in self.pg_interfaces: i.admin_down() super(TestPipe, self).tearDown() def test_pipe(self): """ Pipes """ pipes = [VppPipe(self), VppPipe(self, 10)] for p in pipes: p.add_vpp_config() p.admin_up() # # L2 cross-connect pipe0 east with pg0 and west with pg1 # self.vapi.sw_interface_set_l2_xconnect(self.pg0.sw_if_index, pipes[0].east, enable=1) self.vapi.sw_interface_set_l2_xconnect(pipes[0].east, self.pg0.sw_if_index, enable=1) self.vapi.sw_interface_set_l2_xconnect(self.pg1.sw_if_index, pipes[0].west, enable=1) self.vapi.sw_interface_set_l2_xconnect(pipes[0].west, self.pg1.sw_if_index, enable=1) # test bi-drectional L2 flow pg0<->pg1 p = (Ether(src=self.pg0.remote_mac, dst=self.pg1.remote_mac) / IP(src="1.1.1.1", dst="1.1.1.2") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) self.send_and_expect(self.pg0, p * 65, self.pg1) self.send_and_expect(self.pg1, p * 65, self.pg0) # # Attach ACL to ensure features are run on the pipe # rule_1 = ({'is_permit': 0, 'is_ipv6': 0, 'proto': 17, 'srcport_or_icmptype_first': 1234, 'srcport_or_icmptype_last': 1234, 'src_ip_prefix_len': 32, 'src_ip_addr': inet_pton(AF_INET, "1.1.1.1"), 'dstport_or_icmpcode_first': 1234, 'dstport_or_icmpcode_last': 1234, 'dst_ip_prefix_len': 32, 'dst_ip_addr': inet_pton(AF_INET, "1.1.1.2")}) acl = self.vapi.acl_add_replace(acl_index=4294967295, r=[rule_1]) # Apply the ACL on the pipe on output self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, [acl.acl_index]) self.send_and_assert_no_replies(self.pg0, p * 65) self.send_and_expect(self.pg1, p * 65, self.pg0) # remove from output and apply on input self.vapi.acl_interface_set_acl_list(pipes[0].east, 0, []) self.vapi.acl_interface_set_acl_list(pipes[0].west, 1, [acl.acl_index]) self.send_and_assert_no_replies(self.pg0, p * 65) self.send_and_expect(self.pg1, p * 65, self.pg0) self.vapi.acl_interface_set_acl_list(pipes[0].west, 0, []) self.send_and_expect(self.pg0, p * 65, self.pg1) self.send_and_expect(self.pg1, p * 65, self.pg0) # # L3 routes in two separate tables so a pipe can be used to L3 # x-connect # tables = [] tables.append(VppIpTable(self, 1)) tables.append(VppIpTable(self, 2)) for t in tables: t.add_vpp_config() self.pg2.set_table_ip4(1) self.pg2.config_ip4() self.pg2.resolve_arp() self.pg3.set_table_ip4(2) self.pg3.config_ip4() self.pg3.resolve_arp() routes = [] routes.append(VppIpRoute(self, "1.1.1.1", 32, [VppRoutePath(self.pg3.remote_ip4, self.pg3.sw_if_index)], table_id=2)) routes.append(VppIpRoute(self, "1.1.1.1", 32, [VppRoutePath("0.0.0.0", pipes[1].east)], table_id=1)) routes.append(VppIpRoute(self, "1.1.1.2", 32, [VppRoutePath("0.0.0.0", pipes[1].west)], table_id=2)) routes.append(VppIpRoute(self, "1.1.1.2", 32, [VppRoutePath(self.pg2.remote_ip4, self.pg2.sw_if_index)], table_id=1)) for r in routes: r.add_vpp_config() p_east = (Ether(src=self.pg2.remote_mac, dst=self.pg2.local_mac) / IP(src="1.1.1.2", dst="1.1.1.1") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) # bind the pipe ends to the correct tables self.vapi.sw_interface_set_table(pipes[1].west, 0, 2) self.vapi.sw_interface_set_table(pipes[1].east, 0, 1) # IP is not enabled on the pipes at this point self.send_and_assert_no_replies(self.pg2, p_east * 65) # IP enable the Pipes by making them unnumbered pipes[0].set_unnumbered(self.pg2.sw_if_index) pipes[1].set_unnumbered(self.pg3.sw_if_index) self.send_and_expect(self.pg2, p_east * 65, self.pg3) # and the return path p_west = (Ether(src=self.pg3.remote_mac, dst=self.pg3.local_mac) / IP(src="1.1.1.1", dst="1.1.1.2") / UDP(sport=1234, dport=1234) / Raw('\xa5' * 100)) self.send_and_expect(self.pg3, p_west * 65, self.pg2) # # Use ACLs to test features run on the Pipes # self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, [acl.acl_index]) self.send_and_assert_no_replies(self.pg2, p_east * 65) self.send_and_expect(self.pg3, p_west * 65, self.pg2) # remove from output and apply on input self.vapi.acl_interface_set_acl_list(pipes[1].east, 0, []) self.vapi.acl_interface_set_acl_list(pipes[1].west, 1, [acl.acl_index]) self.send_and_assert_no_replies(self.pg2, p_east * 65) self.send_and_expect(self.pg3, p_west * 65, self.pg2) self.vapi.acl_interface_set_acl_list(pipes[1].west, 0, []) self.send_and_expect(self.pg2, p_east * 65, self.pg3) self.send_and_expect(self.pg3, p_west * 65, self.pg2) # cleanup (so the tables delete) self.pg2.unconfig_ip4() self.pg2.set_table_ip4(0) self.pg3.unconfig_ip4() self.pg3.set_table_ip4(0) self.vapi.sw_interface_set_table(pipes[1].west, 0, 0) self.vapi.sw_interface_set_table(pipes[1].east, 0, 0) if __name__ == '__main__': unittest.main(testRunner=VppTestRunner)