1 ---------------------------------
3 --- @brief Longest Prefix Matching ...
5 ---------------------------------
7 local
ffi = require
"ffi"
10 local
band, lshift, rshift = bit.band, bit.lshift, bit.rshift
11 local dpdkc = require
"dpdkc"
12 local dpdk = require
"dpdk"
13 local serpent = require
"Serpent"
15 --local burst = require
"burst"
19 struct rte_table_lpm_params {
21 uint32_t entry_unique_size;
24 void * mg_table_lpm_create(
void *params,
int socket_id, uint32_t entry_size);
25 int mg_table_lpm_free(
void *table);
26 int mg_table_entry_add_simple(
31 int mg_table_lpm_entry_add(
38 int mg_table_lpm_lookup(
40 struct rte_mbuf **pkts,
42 uint64_t *lookup_hit_mask,
44 int mg_table_lpm_lookup_big_burst(
46 struct rte_mbuf **pkts,
47 struct mg_bitmask* pkts_mask,
48 struct mg_bitmask* lookup_hit_mask,
50 int mg_table_lpm_entry_delete(
56 void ** mg_lpm_table_allocate_entry_prts(uint16_t n_entries);
57 int printf(
const char *fmt, ...);
59 int mg_table_lpm_apply_route(
60 struct rte_mbuf **pkts,
61 struct mg_bitmask* pkts_mask,
63 uint16_t offset_entry,
72 local mg_lpm4Table = {}
73 mod.mg_lpm4Table = mg_lpm4Table
74 mg_lpm4Table.__index = mg_lpm4Table
76 --- Create a
new LPM
lookup table.
77 --- @param socket
optional (
default = socket of the calling thread), CPU socket, where memory
for the table should be allocated.
78 --- @
return the table handler
79 function mod.createLpm4Table(socket, table, entry_ctype)
80 socket = socket or select(2, dpdk.getCore())
81 -- configure parameters
for the LPM table
82 local params =
ffi.new(
"struct rte_table_lpm_params")
84 params.entry_unique_size = 5
85 --params.offset = 128 + 27+4
86 params.offset = 128+ 14 + 12+4
88 table = table or
ffi.gc(
ffi.C.mg_table_lpm_create(params, socket,
ffi.sizeof(entry_ctype)),
function(
self)
89 -- FIXME: why is destructor never called?
91 ffi.C.mg_table_lpm_free(
self)
93 entry_ctype = entry_ctype
97 -- --- Free the LPM Table
98 -- --- @return 0 on success, error code otherwise
99 -- function mg_lpm4Table:destruct()
100 -- return
ffi.C.mg_table_lpm_free(self.table)
103 --- Add an entry to a Table
104 --- @param addr IPv4 network address of the destination network.
105 --- @param depth number of significant bits of the destination network address
106 --- @param entry routing table entry (will be copied)
107 --- @return true if entry was added without error
108 function mg_lpm4Table:
addEntry(addr, depth, entry)
109 return 0 ==
ffi.C.mg_table_entry_add_simple(self.table, addr, depth, entry)
112 --- Perform IPv4 route
lookup for a burst of packets
113 --- This should not be used for single packet
lookup, as ist brings
114 --- a significant penalty for bursts <<64
115 --- @param packets Array of mbufs (
bufArray), for which the lookup will be performed
116 --- @param mask
optional (default = all packets), bitmask, for which packets the lookup should be performed
117 --- @param hitMask Bitmask, where the routed packets are flagged
118 --- with one. This may be the same Bitmask as passed in the mask
119 --- parameter, in this case not routed packets will be cleared in
121 --- @param entries Preallocated routing entry Pointers
122 function mg_lpm4Table:
lookupBurst(packets, mask, hitMask, entries)
123 -- FIXME: I feel uneasy about this cast, should this cast not be
125 return
ffi.C.mg_table_lpm_lookup_big_burst(self.table, packets.array, mask.bitmask, hitMask.bitmask,
ffi.cast("
void **",entries.array))
128 function mg_lpm4Table:__serialize()
129 return "require 'lpm'; return " .. serpent.addMt(serpent.dumpRaw(self), "require('lpm').mg_lpm4Table"), true
132 --- Allocates an LPM table entry
133 --- @return The newly allocated entry
135 return
ffi.
new(self.entry_ctype)
138 local mg_lpm4EntryPtrs = {}
140 --- Allocates an array of pointers to routing table entries
141 --- This is used during burst
lookup, to store references to the
143 --- @param
n Number of entry pointers
144 --- @
return Wrapper table around the allocated array
146 --
return ffi.C.mg_lpm_table_allocate_entry_prts(
n)
147 return setmetatable({
148 array =
ffi.new(
self.entry_ctype ..
"*[?]",
n)
152 function mg_lpm4EntryPtrs:__index(k)
153 if type(k) == "number" then
154 return self.array[k - 1]
156 return mg_lpm4EntryPtrs[k]
160 function
mod.applyRoute(pkts, mask, entries, entryOffset)
161 entryOffset = entryOffset or 1
162 return
ffi.C.mg_table_lpm_apply_route(pkts.array, mask.bitmask,
ffi.cast("
void **", entries.array), entryOffset, 128, 6)
165 --- FIXME: this should not be in LPM module. but where?
166 --- Decrements the IP TTL field of all masked packets by one.
167 --- out_mask masks the successfully decremented packets (TTL did not reach zero).
169 ipv4 = ipv4 == nil or ipv4
171 -- TODO: C implementation might be faster...
172 for i,
pkt in ipairs(pkts) do
175 local ttl = ipkt.ip4:
getTTL()
188 errorf("TTL decrement for ipv6 not yet implemented")
param n optional(default=2047)
Create a new memory pool.
local ffi
low-level dpdk wrapper
function mg_lpm4Table addEntry(addr, depth, entry)
Add an entry to a Table.
function mod band(mask1, mask2, result)
Bitwise and.
function mg_lpm4Table allocateEntryPtrs(n)
Allocates an array of pointers to routing table entries This is used during burst lookup...
function mempool bufArray(n)
Create a new array of memory buffers (initialized to nil).
local mod
high-level dpdk wrapper
function printf(str,...)
Print a formatted string.
local ip
IP4 protocol constants.
function arp lookup(ip)
Perform a lookup in the ARP table.
local pkt
Module for packets (rte_mbuf)
function mod decrementTTL(pkts, in_mask, out_mask, ipv4)
FIXME: this should not be in LPM module.
n
Create a new array of memory buffers (initialized to nil).
function ip4Header getTTL()
Retrieve the time-to-live.
function errorf(str,...)
Print a formatted error string.
function ip4Header setTTL(int)
Set the time-to-live (TTL).
function mg_lpm4Table allocateEntry()
Allocates an LPM table entry.
function mg_lpm4Table lookupBurst(packets, mask, hitMask, entries)
Perform IPv4 route lookup for a burst of packets This should not be used for single packet lookup...
pkt getIPPacket
Cast the packet to either an IP4 (nil/true) or IP6 (false) packet, depending on the passed boolean...