MoonGen
 All Files Functions Variables Pages
filter_ixgbe.lua
Go to the documentation of this file.
1 ---------------------------------
2 --- @file filter_ixgbe.lua
3 --- @brief Filter for IXGBE ...
4 --- @todo TODO docu
5 ---------------------------------
6 
7 local mod = {}
8 
9 local dpdkc = require "dpdkc"
10 local device = require "device"
11 local ffi = require "ffi"
12 local dpdk = require "dpdk"
13 local mbitmask = require "bitmask"
14 local err = require "error"
15 
16 local ETQF_BASE = 0x00005128
17 local ETQS_BASE = 0x0000EC00
18 
19 local ETQF_FILTER_ENABLE = bit.lshift(1, 31)
20 local ETQF_IEEE_1588_TIME_STAMP = bit.lshift(1, 30)
21 
22 local ETQS_RX_QUEUE_OFFS = 16
23 local ETQS_QUEUE_ENABLE = bit.lshift(1, 31)
24 
25 local ETQF = {}
26 for i = 0, 7 do
27  ETQF[i] = ETQF_BASE + 4 * i
28 end
29 local ETQS = {}
30 for i = 0, 7 do
31  ETQS[i] = ETQS_BASE + 4 * i
32 end
33 
34 ffi.cdef[[
35 struct rte_5tuple_filter {
36  uint32_t dst_ip; /**< destination IP address in big endian. */
37  uint32_t src_ip; /**< source IP address in big endian. */
38  uint16_t dst_port; /**< destination port in big endian. */
39  uint16_t src_port; /**< source Port big endian. */
40  uint8_t protocol; /**< l4 protocol. */
41  uint8_t tcp_flags; /**< tcp flags. */
42  uint16_t priority; /**< seven evels (001b-111b), 111b is highest,
43  used when more than one filter matches. */
44  uint8_t dst_ip_mask:1, /**< if mask is 1b, do not compare dst ip. */
45  src_ip_mask:1, /**< if mask is 1b, do not compare src ip. */
46  dst_port_mask:1, /**< if mask is 1b, do not compare dst port. */
47  src_port_mask:1, /**< if mask is 1b, do not compare src port. */
48  protocol_mask:1; /**< if mask is 1b, do not compare protocol. */
49 };
50 
51 int rte_eth_dev_add_5tuple_filter ( uint8_t port_id,
52  uint16_t index,
53  struct rte_5tuple_filter * filter,
54  uint16_t rx_queue
55  );
56 int
57 mg_5tuple_add_HWfilter_ixgbe(uint8_t port_id, uint16_t index,
58  struct rte_5tuple_filter *filter, uint16_t rx_queue);
59 ]]
60 
61 function mod.l2Filter(dev, etype, queue)
62  if queue == -1 then
63  queue = 127
64  end
65  dpdkc.write_reg32(dev.id, ETQF[1], bit.bor(ETQF_FILTER_ENABLE, etype))
66  dpdkc.write_reg32(dev.id, ETQS[1], bit.bor(ETQS_QUEUE_ENABLE, bit.lshift(queue, ETQS_RX_QUEUE_OFFS)))
67 end
68 
69 --- Installs a 5tuple filter on the device.
70 --- Matching packets will be redirected into the specified rx queue
71 --- NOTE: this is currently only tested for X540 NICs, and will probably also
72 --- work for 82599 and other ixgbe NICs. Use on other NICs might result in
73 --- undefined behavior.
74 --- @param filter A table describing the filter. Possible fields are
75 --- src_ip : Sourche IPv4 Address
76 --- dst_ip : Destination IPv4 Address
77 --- src_port : Source L4 port
78 --- dst_port : Destination L4 port
79 --- l4protocol: L4 Protocol type
80 --- supported protocols: ip.PROTO_ICMP, ip.PROTO_TCP, ip.PROTO_UDP
81 --- If a non supported type is given, the filter will only match on
82 --- protocols, which are not supported.
83 --- All fields are optional.
84 --- If a field is not present, or nil, the filter will ignore this field when
85 --- checking for a match.
86 --- @param queue RX Queue, where packets, matching this filter will be redirected
87 --- @param priority optional (default = 1) The priority of this filter rule.
88 --- 7 is the highest priority and 1 the lowest priority.
89 function mod.addHW5tupleFilter(dev, filter, queue, priority)
90  local sfilter = ffi.new("struct rte_5tuple_filter")
91  sfilter.src_ip_mask = (filter.src_ip == nil) and 1 or 0
92  sfilter.dst_ip_mask = (filter.dst_ip == nil) and 1 or 0
93  sfilter.src_port_mask = (filter.src_port == nil) and 1 or 0
94  sfilter.dst_port_mask = (filter.dst_port == nil) and 1 or 0
95  sfilter.protocol_mask = (filter.l4protocol == nil) and 1 or 0
96 
97  sfilter.priority = priority or 1
98  if(sfilter.priority > 7 or sfilter.priority < 1) then
99  ferror("Filter priority has to be a number from 1 to 7")
100  return
101  end
102 
103  sfilter.src_ip = filter.src_ip or 0
104  sfilter.dst_ip = filter.dst_ip or 0
105  sfilter.src_port = filter.src_port or 0
106  sfilter.dst_port = filter.dst_port or 0
107  sfilter.protocol = filter.l4protocol or 0
108  --if (filter.l4protocol) then
109  -- print "[WARNING] Protocol filter not yet fully implemented and tested"
110  --end
111 
112  if dev.filters5Tuple == nil then
113  dev.filters5Tuple = {}
114  dev.filters5Tuple.n = 0
115  end
116  dev.filters5Tuple[dev.filters5Tuple.n] = sfilter
117  local idx = dev.filters5Tuple.n
118  dev.filters5Tuple.n = dev.filters5Tuple.n + 1
119 
120  local state
121  if (dev:getPciId() == device.PCI_ID_X540) then
122  -- TODO: write a proper patch for dpdk
123  state = ffi.C.mg_5tuple_add_HWfilter_ixgbe(dev.id, idx, sfilter, queue.qid)
124  else
125  state = ffi.C.rte_eth_dev_add_5tuple_filter(dev.id, idx, sfilter, queue.qid)
126  end
127 
128  if (state ~= 0) then
129  errorf("Filter not successfully added: %s", err.getstr(-state))
130  end
131 
132  return idx
133 end
134 
135 return mod
param n optional(default=2047)
Create a new memory pool.
local ffi
low-level dpdk wrapper
Definition: dpdkc.lua:6
function mod new(n)
local mod
high-level dpdk wrapper
Definition: dpdk.lua:6
local ip
IP4 protocol constants.
Definition: ip4.lua:25
function errorf(str,...)
Print a formatted error string.
function mod addHW5tupleFilter(dev, filter, queue, priority)
Installs a 5tuple filter on the device.