Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stateful NFV Packet Filtering #403

Merged
merged 6 commits into from
Mar 20, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 54 additions & 0 deletions src/apps/packet_filter/packet_filter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,60 @@ function selftest ()
print ("state app_v4 failed")
end

-- part 3:
app.configure(config.new())
c = config.new()

config.app(c, "source1", pcap.PcapReader, "apps/packet_filter/samples/v4-tcp-udp.pcap")
config.app(c, "stateless_pass1", PacketFilter, {
rules = {
{
ethertype = "ipv4",
dest_port_min = 12345,
protocol = "tcp",
},
},
})
config.app(c, "sink1", basic_apps.Sink )
config.link(c, "source1.output -> stateless_pass1.input")
config.link(c, "stateless_pass1.output -> sink1.input")

app.configure(c)
app.breathe()
app.report()

if app.app_table.stateless_pass1.output.output.stats.txpackets ~= 1 then
ok = false
print ("stateless tcp failed")
end

app.configure(config.new())
c = config.new()

config.app(c, "source1", pcap.PcapReader, "apps/packet_filter/samples/v6-tcp-udp.pcap")
config.app(c, "stateless_pass1", PacketFilter, {
rules = {
{
ethertype = "ipv6",
dest_port_min = 1022,
protocol = "tcp",
},
},
})
config.app(c, "sink1", basic_apps.Sink )
config.link(c, "source1.output -> stateless_pass1.input")
config.link(c, "stateless_pass1.output -> sink1.input")

app.configure(c)
app.breathe()
app.report()

if app.app_table.stateless_pass1.output.output.stats.txpackets ~= 1 then
ok = false
print ("stateless v6 tcp failed")
end


if not ok then
print("selftest failed")
os.exit(1)
Expand Down
Binary file added src/apps/packet_filter/samples/v4-tcp-udp.pcap
Binary file not shown.
Binary file added src/apps/packet_filter/samples/v6-tcp-udp.pcap
Binary file not shown.
2 changes: 1 addition & 1 deletion src/program/snabbnfv/fuzz/fuzz.lua
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ function fuzz_connective_ports (spec)
for i = 1, n_rules do
rules[i+2] = random_filter_rule()
end
return rules
return { rules = rules }
end
local function fuzz_tunnel ()
local cookies = { random_cookie(), random_cookie() }
Expand Down
15 changes: 10 additions & 5 deletions src/program/snabbnfv/neutron2snabb/neutron2snabb.lua
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ function create_config (input_dir, output_dir, hostname)
{ vlan = vif_details.zone_vlan,
mac_address = port.mac_address,
port_id = port.id,
ingress_filter = filter(port, secbindings, secrules, 'ingress'),
egress_filter = filter(port, secbindings, secrules, 'egress'),
ingress_filter = filter(port, secbindings, secrules, 'ingress', profile.packetfilter),
egress_filter = filter(port, secbindings, secrules, 'egress', profile.packetfilter),
gbps = vif_details.zone_gbps,
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The packetfilter setting should be in profile rather than vif_details.

@lukego This line looks a bit fishy too now that I think about it. We never use the gbps field in nfvconfig... (and some sort of tx_police_gbps is missing too).

rx_police_gbps = profile.rx_police_gbps,
tunnel = tunnel(port, vif_details, profile) })
Expand All @@ -77,7 +77,7 @@ function create_config (input_dir, output_dir, hostname)
end

-- Return the packet filter expression.
function filter (port, secbindings, secrules, direction)
function filter (port, secbindings, secrules, direction, type)
local rules = {}
direction = direction:lower()
if secbindings[port.id] then
Expand All @@ -95,9 +95,14 @@ function filter (port, secbindings, secrules, direction)
end
end
end
if type == "stateless" then
return { rules = rules }
else
return { rules = rules,
state_track = port.id,
state_check = port.id }
end
end
if #rules > 0 then return { rules = rules }
else return nil end
end

-- Return the L2TPv3 tunnel expresion.
Expand Down
24 changes: 20 additions & 4 deletions src/program/snabbnfv/selftest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ function test_rate_limited {
# <dest_ip>/<port> on VM listening on <telnet_port1>. If `-u' is appended
# UDP is used instead of TCP.
function port_probe {
run_telnet $2 "nohup echo | nc $5 -l $3 $4 &" 2>&1 >/dev/null
run_telnet $1 "nc -v $5 $3 $4" 5 | agrep succeeded
run_telnet $2 "nohup echo | nc -q 1 $5 -l $3 $4 &" 2>&1 >/dev/null
run_telnet $1 "nc -w 1 -q 1 -v $5 $3 $4" 5 | agrep succeeded
}

function same_vlan_tests {
Expand Down Expand Up @@ -285,8 +285,24 @@ function filter_tests {
test 0 -ne $?
assert FILTER $?

# Assert UDP/12345 is filtered.
port_probe $TELNET_PORT0 $TELNET_PORT1 "$GUEST_IP1%eth0" 12345 -u

load_config program/snabbnfv/test_fixtures/nfvconfig/test_functions/stateful-filter.ports

# port B allows ICMP and TCP/12345 ingress and established egress
# traffic.

test_ping $TELNET_PORT0 "$GUEST_IP1%eth0"

port_probe $TELNET_PORT0 $TELNET_PORT1 "$GUEST_IP1%eth0" 12345
assert PORTPROBE $?

# Assert TCP/12346 is filtered.
port_probe $TELNET_PORT0 $TELNET_PORT1 "$GUEST_IP1%eth0" 12348
test 0 -ne $?
assert FILTER $?

# Assert non-established egress connections are filtered.
port_probe $TELNET_PORT1 $TELNET_PORT0 "$GUEST_IP0%eth0" 12340
test 0 -ne $?
assert FILTER $?
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
return {
{ vlan = 0,
mac_address = "52:54:00:00:00:00",
port_id = "A"
},
{ vlan = 0,
mac_address = "52:54:00:00:00:01",
port_id = "B",
ingress_filter = { rules = { { ethertype='ipv6',
protocol='icmp' },
{ ethertype='ipv6',
protocol='tcp',
dest_port_min=12345 } },
state_track = "test" },
egress_filter = { rules = { { ethertype='ipv6',
protocol='icmp' } },
state_check = "test" }
},
}