| 69 | |
| 70 | |
| 71 | class RSSAlgo: |
| 72 | def __init__( |
| 73 | self, |
| 74 | queues_count: int, |
| 75 | key: bytes, |
| 76 | reta_size: int, |
| 77 | use_l4_port: bool, |
| 78 | ): |
| 79 | self.queues_count = queues_count |
| 80 | self.reta = tuple(i % queues_count for i in range(reta_size)) |
| 81 | self.key = key |
| 82 | self.use_l4_port = use_l4_port |
| 83 | |
| 84 | def toeplitz_hash(self, data: bytes) -> int: |
| 85 | # see rte_softrss_* in lib/hash/rte_thash.h |
| 86 | hash_value = ctypes.c_uint32(0) |
| 87 | |
| 88 | for i, byte in enumerate(data): |
| 89 | for j in range(8): |
| 90 | bit = (byte >> (7 - j)) & 0x01 |
| 91 | |
| 92 | if bit == 1: |
| 93 | keyword = ctypes.c_uint32(0) |
| 94 | keyword.value |= self.key[i] << 24 |
| 95 | keyword.value |= self.key[i + 1] << 16 |
| 96 | keyword.value |= self.key[i + 2] << 8 |
| 97 | keyword.value |= self.key[i + 3] |
| 98 | |
| 99 | if j > 0: |
| 100 | keyword.value <<= j |
| 101 | keyword.value |= self.key[i + 4] >> (8 - j) |
| 102 | |
| 103 | hash_value.value ^= keyword.value |
| 104 | |
| 105 | return hash_value.value |
| 106 | |
| 107 | def get_queue_index(self, packet: Packet) -> int: |
| 108 | bytes_to_hash = packet.hash_data(self.use_l4_port) |
| 109 | |
| 110 | # get the 32bit hash of the packet |
| 111 | hash_value = self.toeplitz_hash(bytes_to_hash) |
| 112 | |
| 113 | # determine the offset in the redirection table |
| 114 | offset = hash_value & (len(self.reta) - 1) |
| 115 | |
| 116 | return self.reta[offset] |
| 117 | |
| 118 | |
| 119 | def balanced_traffic( |