Skip to content

Commit

Permalink
l2vpn: access interface counters via read-only shm frames
Browse files Browse the repository at this point in the history
Instead of accessing the private shm frames that hold the stats
counters of the devices, use copies via open_frame().
  • Loading branch information
alexandergall committed Jul 27, 2017
1 parent 9bec79f commit 47aee50
Showing 1 changed file with 59 additions and 6 deletions.
65 changes: 59 additions & 6 deletions src/program/l2vpn/l2vpn.lua
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ local vmux = require("apps.vlan.vlan").VlanMux
local ifmib = require("lib.ipc.shmem.iftable_mib")
local counter = require("core.counter")
local macaddress = require("lib.macaddress")
local shm = require("core.shm")

-- config = {
-- [ shmem_dir = <shmem_dir> , ]
Expand Down Expand Up @@ -236,6 +237,35 @@ function config_if (c, afs, app_c)
end
end

-- Helper functions to abstract from driver-specific behaviour. The
-- key into this table is the full path to the module used to create
-- the driver object. For each driver, the following functions must be
-- defined
-- link_names ()
-- Return the name of the links used for input and ouput
-- stats_path (driver)
-- This function is called after the driver has been created
-- and receives the driver object as input. It returns the
-- path to the shm frame where the driver stores its stats counters.
local driver_helpers = {
['apps.intel_mp.intel_mp.Intel'] = {
link_names = function ()
return 'input', 'output'
end,
stats_path = function (driver)
return driver.stats.path
end
},
['apps.tap.tap.Tap'] = {
link_names = function ()
return 'input', 'output'
end,
stats_path = function (driver)
return driver.shm.path
end
},
}

function parse_if (if_app_name, config)
local result = { name = if_app_name,
description = config.description,
Expand Down Expand Up @@ -272,8 +302,11 @@ function parse_if (if_app_name, config)
-- use "input" and "output", but this has not yet been
-- standardized (and the old inel{1,10}g drivers uses a
-- different convention).
result.input = "input"
result.output = "output"
local driver_helper = driver_helpers[drv_c.path.."."..drv_c.name]
assert(driver_helper,
"Unsupported driver "..drv_c.path.."."..drv_c.name)
result.driver_helper = driver_helper
result.input, result.output = driver_helper.link_names()
local l3_links = { input = if_app_name.."."..result.input,
output = if_app_name.."."..result.output }

Expand Down Expand Up @@ -417,6 +450,15 @@ function parse_if (if_app_name, config)
return config.name, result
end

function intf_from_app_name (intfs, app_name)
for _, intf in pairs(intfs) do
if intf.name == app_name then
return intf
end
end
return nil
end

function run (parameters)
local duration = 0
local jit_conf = {}
Expand Down Expand Up @@ -674,15 +716,27 @@ function run (parameters)
end
engine.configure(c)

-- For each interface, attach to the shm frame that stores
-- the statistics counters
for _, intf in pairs(intfs) do
local app = engine.app_table[intf.name]
intf.stats = shm.open_frame(intf.driver_helper.stats_path(app))
end
-- Commit all counters to the backing store to make them available
-- immediately through the read-only frames we just created
counter.commit()

-- The physical MAC addresses of the interfaces are only known
-- after the drivers have been configured. We need to reconfigure
-- all relevant ND apps to use those MAC addresses as their "local"
-- MAC.
local function reconfig_mac(nd)
local app = engine.app_table[nd.name]
if app then
local if_app = nd.if_app_name
local stats = intf_from_app_name(intfs, if_app).stats
nd.config.local_mac =
macaddress:new(counter.read(engine.app_table[nd.if_app_name].stats.macaddr)).bytes
macaddress:new(counter.read(stats.macaddr)).bytes
app:reconfig(nd.config)
end
end
Expand All @@ -708,9 +762,8 @@ function run (parameters)
-- Set up SNMP for physical interfaces
local app = engine.app_table[intf.name]
if app == nil then goto continue end
-- Assume that all drivers store their stats
-- like this.
local stats = app.stats
if engine.app_table[intf.name] == nil then goto continue end
local stats = intf.stats
if stats then
ifmib.init_snmp( { ifDescr = name,
ifName = name,
Expand Down

0 comments on commit 47aee50

Please sign in to comment.