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

Table app args refactoring #293

Merged
merged 4 commits into from
Nov 4, 2014
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
73 changes: 34 additions & 39 deletions src/apps/intel/intel_app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -24,20 +24,20 @@ end


-- Create an Intel82599 App for the device with 'pciaddress'.
function Intel82599:new (args)
args = config.parse_app_arg(args)
function Intel82599:new (arg)
local conf = config.parse_app_arg(arg)
Copy link
Member Author

Choose a reason for hiding this comment

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

Prepend local.


if args.vmdq then
if devices[args.pciaddr] == nil then
devices[args.pciaddr] = {pf=intel10g.new_pf(args.pciaddr):open(), vflist={}}
if conf.vmdq then
if devices[conf.pciaddr] == nil then
devices[conf.pciaddr] = {pf=intel10g.new_pf(conf.pciaddr):open(), vflist={}}
end
local dev = devices[args.pciaddr]
local dev = devices[conf.pciaddr]
local poolnum = firsthole(dev.vflist)-1
local vf = dev.pf:new_vf(poolnum)
dev.vflist[poolnum+1] = vf
return setmetatable({dev=vf:open(args)}, Intel82599)
return setmetatable({dev=vf:open(conf)}, Intel82599)
else
local dev = intel10g.new_sf(args.pciaddr)
local dev = intel10g.new_sf(conf.pciaddr)
:open()
:autonegotiate_sfi()
:wait_linkup()
Expand Down Expand Up @@ -210,8 +210,8 @@ function sq_sq(pcidevA, pcidevB)
print ('just send a lot of packets through the wire')
config.app(c, 'source1', basic_apps.Source)
config.app(c, 'source2', basic_apps.Source)
config.app(c, 'nicA', Intel82599, ([[{pciaddr='%s'}]]):format(pcidevA))
config.app(c, 'nicB', Intel82599, ([[{pciaddr='%s'}]]):format(pcidevB))
config.app(c, 'nicA', Intel82599, {pciaddr=pcidevA})
config.app(c, 'nicB', Intel82599, {pciaddr=pcidevB})
config.app(c, 'sink', basic_apps.Sink)
config.link(c, 'source1.out -> nicA.rx')
config.link(c, 'source2.out -> nicB.rx')
Expand Down Expand Up @@ -244,23 +244,20 @@ function mq_sq(pcidevA, pcidevB)
local c = config.new()
config.app(c, 'source_ms', basic_apps.Join)
config.app(c, 'repeater_ms', basic_apps.Repeater)
config.app(c, 'nicAs', Intel82599, ([[{
-- Single App on NIC A
pciaddr = '%s',
macaddr = '52:54:00:01:01:01',
}]]):format(pcidevA))
config.app(c, 'nicBm0', Intel82599, ([[{
-- first VF on NIC B
pciaddr = '%s',
vmdq = true,
macaddr = '52:54:00:02:02:02',
}]]):format(pcidevB))
config.app(c, 'nicBm1', Intel82599, ([[{
-- second VF on NIC B
pciaddr = '%s',
vmdq = true,
macaddr = '52:54:00:03:03:03',
}]]):format(pcidevB))
config.app(c, 'nicAs', Intel82599,
{-- Single App on NIC A
pciaddr = pcidevA,
macaddr = '52:54:00:01:01:01'})
config.app(c, 'nicBm0', Intel82599,
{-- first VF on NIC B
pciaddr = pcidevB,
vmdq = true,
macaddr = '52:54:00:02:02:02'})
config.app(c, 'nicBm1', Intel82599,
{-- second VF on NIC B
pciaddr = pcidevB,
vmdq = true,
macaddr = '52:54:00:03:03:03'})
print ('-------')
print ("Send a bunch of from the SF on NIC A to the VFs on NIC B")
print ("half of them go to nicBm0 and nicBm0")
Expand Down Expand Up @@ -299,18 +296,16 @@ function mq_sw(pcidevA)
local c = config.new()
config.app(c, 'source_ms', basic_apps.Join)
config.app(c, 'repeater_ms', basic_apps.Repeater)
config.app(c, 'nicAm0', Intel82599, ([[{
-- first VF on NIC A
pciaddr = '%s',
vmdq = true,
macaddr = '52:54:00:01:01:01',
}]]):format(pcidevA))
config.app(c, 'nicAm1', Intel82599, ([[{
-- second VF on NIC A
pciaddr = '%s',
vmdq = true,
macaddr = '52:54:00:02:02:02',
}]]):format(pcidevA))
config.app(c, 'nicAm0', Intel82599,
{-- first VF on NIC A
pciaddr = pcidevA,
vmdq = true,
macaddr = '52:54:00:01:01:01'})
config.app(c, 'nicAm1', Intel82599,
{-- second VF on NIC A
pciaddr = pcidevA,
vmdq = true,
macaddr = '52:54:00:02:02:02'})
print ('-------')
print ("Send a bunch of packets from Am0")
print ("half of them go to nicAm1 and half go nowhere")
Expand Down
5 changes: 2 additions & 3 deletions src/apps/ipv6/ipv6.lua
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,8 @@ struct {

SimpleIPv6 = {}

function SimpleIPv6:new (confstring)
print("confstring", confstring)
local conf = confstring and loadstring("return " .. confstring)() or {}
function SimpleIPv6:new (arg)
local conf = config and config.parse_app_arg(arg) or {}
own_mac = conf.own_mac or "\x52\x54\x00\x12\x34\x57"
own_ip = conf.own_ip or "\x00\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x01"
local o = {own_mac = own_mac, own_ip = own_ip}
Expand Down
43 changes: 20 additions & 23 deletions src/apps/keyed_ipv6_tunnel/tunnel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -102,8 +102,8 @@ end

SimpleKeyedTunnel = {}

function SimpleKeyedTunnel:new (confstring)
local config = confstring and loadstring("return " .. confstring)() or {}
function SimpleKeyedTunnel:new (arg)
local conf = arg and config.parse_app_arg(arg) or {}
-- required fields:
-- local_address, string, ipv6 address
-- remote_address, string, ipv6 address
Expand All @@ -114,23 +114,22 @@ function SimpleKeyedTunnel:new (confstring)
-- default_gateway_MAC, useful for testing
-- hop_limit, override default hop limit 64
assert(
type(config.local_cookie) == "string"
and #config.local_cookie <= 16,
type(conf.local_cookie) == "string"
and #conf.local_cookie <= 16,
"local_cookie should be 8 bytes hex string"
)
config.local_cookie = lib.hexundump(config.local_cookie, 8)
assert(
Copy link
Member Author

Choose a reason for hiding this comment

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

When I went over this I realized how bad this is (destructively modifying the conf, which might be shared if it was passed as a table). So I sneaked in a fixup here, see lines 127 and 148.

type(config.remote_cookie) == "string"
and #config.remote_cookie <= 16,
type(conf.remote_cookie) == "string"
and #conf.remote_cookie <= 16,
"remote_cookie should be 8 bytes hex string"
)
config.remote_cookie = lib.hexundump(config.remote_cookie, 8)
local header = header_array_ctype(HEADER_SIZE)
ffi.copy(header, header_template, HEADER_SIZE)
local local_cookie = lib.hexundump(conf.local_cookie, 8)
ffi.copy(
header + COOKIE_OFFSET,
config.local_cookie,
#config.local_cookie
local_cookie,
#local_cookie
)

-- convert dest, sorce ipv6 addressed to network order binary
Expand All @@ -146,22 +145,22 @@ function SimpleKeyedTunnel:new (confstring)
local remote_address = ffi.cast(paddress_ctype, header + DST_IP_OFFSET)
local local_address = ffi.cast(paddress_ctype, header + SRC_IP_OFFSET)

local remote_cookie = ffi.cast(pcookie_ctype, config.remote_cookie)
local remote_cookie = ffi.cast(pcookie_ctype, lib.hexundump(conf.remote_cookie, 8))

if config.local_session then
if conf.local_session then
local psession = ffi.cast(psession_id_ctype, header + SESSION_ID_OFFSET)
psession[0] = lib.htonl(config.local_session)
psession[0] = lib.htonl(conf.local_session)
end

if config.default_gateway_MAC then
local mac = assert(macaddress:new(config.default_gateway_MAC))
if conf.default_gateway_MAC then
local mac = assert(macaddress:new(conf.default_gateway_MAC))
ffi.copy(header + DST_MAC_OFFSET, mac.bytes, 6)
end

if config.hop_limit then
assert(type(config.hop_limit) == 'number' and
config.hop_limit <= 255, "invalid hop limit")
header[HOP_LIMIT_OFFSET] = config.hop_limit
if conf.hop_limit then
assert(type(conf.hop_limit) == 'number' and
conf.hop_limit <= 255, "invalid hop limit")
header[HOP_LIMIT_OFFSET] = conf.hop_limit
end

local o =
Expand Down Expand Up @@ -274,15 +273,13 @@ function selftest ()

local input_file = "apps/keyed_ipv6_tunnel/selftest.cap.input"
local output_file = "apps/keyed_ipv6_tunnel/selftest.cap.output"
local tunnel_config =
[[{
local tunnel_config = {
local_address = "00::2:1",
remote_address = "00::2:1",
local_cookie = "12345678",
remote_cookie = "12345678",
default_gateway_MAC = "a1:b2:c3:d4:e5:f6"
}
]] -- should be symmetric for local "loop-back" test
} -- should be symmetric for local "loop-back" test

buffer.preallocate(10000)
local c = config.new()
Expand Down
4 changes: 2 additions & 2 deletions src/apps/packet_filter/packet_filter.lua
Original file line number Diff line number Diff line change
Expand Up @@ -379,8 +379,8 @@ end

PacketFilter = {}

function PacketFilter:new (confstring)
local rules = confstring and loadstring("return " .. confstring)() or {}
function PacketFilter:new (arg)
local rules = arg and config.parse_app_arg(arg) or {}
assert(rules)
assert(#rules > 0)

Expand Down
14 changes: 7 additions & 7 deletions src/core/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,13 @@ end
-- c is a config object.
-- name is the name of this app in the network (a string).
-- class is the Lua object with a class:new(arg) method to create the app.
-- arg is the app's configuration (as a string to be passed to new()).
-- arg is the app's configuration (to be passed to new()).
--
-- Example: config.app(c, "nic", Intel82599, [[{pciaddr = "0000:00:01.00"}]])
-- Example: config.app(c, "nic", Intel82599, {pciaddr = "0000:00:01.00"})
function app (config, name, class, arg)
arg = arg or "nil"
assert(type(name) == "string", "name must be a string")
assert(type(class) == "table", "class must be a table")
assert(type(arg) == "string" or type(arg) == "table",
"arg must be a string or a table")
config.apps[name] = { class = class, arg = arg}
end

Expand Down Expand Up @@ -59,9 +57,11 @@ end
-- Return a Lua object for the arg to an app.
-- Example:
-- parse_app_arg("{ timeout = 5 * 10 }") => { timeout = 50 }
function parse_app_arg (s)
assert(type(s) == 'string')
return loadstring("return " .. s)()
-- parse_app_arg(<table>) => <table> (NOOP)
function parse_app_arg (arg)
if type(arg) == 'string' then return loadstring("return " .. arg)()
elseif type(arg) == 'table' then return arg
else error("<arg> is not a string or table.") end
end

function graphviz (c)
Expand Down
4 changes: 2 additions & 2 deletions src/designs/csv/csv
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ local v6_rules = [[
config.app(c, "pcap", pcap.PcapReader, "apps/packet_filter/samples/v6.pcap")
config.app(c, "repeat", basic_apps.Repeater)
config.app(c, "limit", rate_limiter.RateLimiter, [[ {rate = 1e8, bucket_capacity = 1e9} ]])
config.app(c, "nic1", Intel82599, [[{pciaddr = "0000:05:00.1"}]])
config.app(c, "nic2", Intel82599, [[{pciaddr = "0000:8a:00.1"}]])
config.app(c, "nic1", Intel82599, {pciaddr = "0000:05:00.1"})
config.app(c, "nic2", Intel82599, {pciaddr = "0000:8a:00.1"})
config.app(c, "filter", packet_filter.PacketFilter, v6_rules)
config.app(c, "tee", basic_apps.Tee)
config.app(c, "sink1", basic_apps.Sink)
Expand Down
2 changes: 1 addition & 1 deletion src/designs/nfv/nfv
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function run (npackets)
pci.unbind_device_from_linux(pciaddr)
local c = config.new()
config.app(c, "vm", vhost_user.VhostUser, {socket_path=socket, is_server=server})
config.app(c, "nic", intel_app.Intel82599, ([[{pciaddr='%s'}]]):format(pciaddr))
config.app(c, "nic", intel_app.Intel82599, {pciaddr=pciaddr})
if not trace then
print("No trace file ($NFV_TRACE) configured.")
config.link(c, "vm.tx -> nic.rx")
Expand Down
24 changes: 10 additions & 14 deletions src/lib/nfv/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,10 @@ function load (file, pciaddr, sockpath)
local name = port_id:gsub("-", "_")
local NIC = "NIC_"..name
local Virtio = "Virtio_"..name
config.app(c, NIC, Intel82599,
([[{pciaddr = %q,
vmdq=true,
macaddr = %q,
vlan=%d}]]):format(pciaddr, mac_address, vlan))
config.app(c, NIC, Intel82599, {pciaddr = pciaddr,
vmdq = true,
macaddr = mac_address,
vlan = vlan})
config.app(c, Virtio, VhostUser, {socket_path=sockpath:format(port_id)})
local VM_rx, VM_tx = Virtio..".rx", Virtio..".tx"
if t.ingress_filter then
Expand All @@ -46,14 +45,11 @@ function load (file, pciaddr, sockpath)
end
if t.tunnel and t.tunnel.type == "L2TPv3" then
local Tunnel = "Tunnel_"..name
local conf = (([[{local_address = %q,
remote_address = %q,
local_cookie = %q,
remote_cookie = %q,
local_session = %q,}]])
:format(t.tunnel.local_ip, t.tunnel.remote_ip,
t.tunnel.local_cookie, t.tunnel.remote_cookie,
t.tunnel.session))
local conf = {local_address = t.tunnel.local_ip,
remote_address = t.tunnel.remote_ip,
local_cookie = t.tunnel.local_cookie,
remote_cookie = t.tunnel.remote_cookie,
local_session = t.tunnel.session}
config.app(c, Tunnel, L2TPv3, conf)
-- Setup IPv6 neighbor discovery/solicitation responder.
-- This will talk to our local gateway.
Expand All @@ -73,7 +69,7 @@ function load (file, pciaddr, sockpath)
if policing and t.gbps then
local QoS = "QoS_"..name
local rate = t.gbps * 1000000 / 8
config.app(c, QoS, RateLimiter, ([[{rate = %d, bucket_capacity = %d}]]):format(rate, rate))
config.app(c, QoS, RateLimiter, {rate = rate, bucket_capacity = rate})
config.link(c, VM_tx.." -> "..QoS..".rx")
VM_tx = QoS..".tx"
end
Expand Down
5 changes: 4 additions & 1 deletion src/test_fixtures/nfvconfig/switch_filter/x
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ return {
{ vlan = 0,
mac_address = "00:90:f5:ef:aa:67",
port_id = "id0",
ingress_filter = [[{ { ethertype='ipv6', protocol='udp', dest_port_min=1024, dest_port_max=1025, }, }]],
ingress_filter = { { ethertype='ipv6',
protocol='udp',
dest_port_min=1024,
dest_port_max=1025 } },
gbps = nil,
tunnel = nil
},
Expand Down
5 changes: 4 additions & 1 deletion src/test_fixtures/nfvconfig/switch_filter/y
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,10 @@ return {
{ vlan = 0,
mac_address = "00:90:f5:ef:aa:67",
port_id = "id0",
ingress_filter = [[{ { ethertype='ipv4', protocol='tcp', dest_port_min=24, dest_port_max=25, }, }]],
ingress_filter = { { ethertype='ipv4',
protocol='tcp',
dest_port_min=24,
dest_port_max=25 } },
gbps = nil,
tunnel = nil
},
Expand Down
10 changes: 5 additions & 5 deletions src/test_fixtures/nfvconfig/test_functions/filter.ports
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ return {
{ vlan = 0,
mac_address = "52:54:00:00:00:01",
port_id = "B",
ingress_filter = [[{ { ethertype='ipv6',
protocol='icmp' },
{ ethertype='ipv6',
protocol='tcp',
dest_port_min=12345 } }]],
ingress_filter = { { ethertype='ipv6',
protocol='icmp' },
{ ethertype='ipv6',
protocol='tcp',
dest_port_min=12345 } },
gbps = nil,
tunnel = nil
},
Expand Down