trex-emu中的plugin是各个协议处理rpc请求及相应协议数据的模块
- trex-emu server 架构图
每个TRex emulation的Thread
包含多个Namespaces
,而每个Namespaces
只能对应到一个Thread
上
每个Namespaces
必须有独一无二的tuple key,其由{physical-port, dot1q, QinQ}组成
每个Client
绑定到一个Namespaces
上,绑定到同一个Namespaces
上的客户端能共享信息
以arp协议plugin为例
- ARP plugin Emulation Server
func init() {
/* register of plugins callbacks for ns,c level */
core.PluginRegister(ARP_PLUG,
core.PluginRegisterData{Client: PluginArpCReg{},
Ns: PluginArpNsReg{},
Thread: nil}) /* no need for thread context for now */
/* The format of the RPC commands xxx_yy_zz_aa
xxx - the plugin name
yy - ns - namespace
c - client
t -thread
zz - cmd command like ping etc
set set configuration
get get configuration/counters
aa - misc
*/
core.RegisterCB("arp_ns_set_cfg", ApiArpNsSetCfgHandler{}, true)
core.RegisterCB("arp_ns_get_cfg", ApiArpNsGetCfgHandler{}, true)
core.RegisterCB("arp_ns_cnt", ApiArpNsCntHandler{}, true)
core.RegisterCB("arp_c_cmd_query", ApiArpCCmdQueryHandler{}, true)
core.RegisterCB("arp_ns_iter", ApiArpNsIterHandler{}, true)
/* register callback for rx side*/
core.ParserRegister("arp", HandleRxArpPacket)
}
func Register(ctx *core.CThreadCtx) {
ctx.RegisterParserCb("arp")
}
以上是arp plugin的入口,其先注册了PluginArpCReg对象和PluginArpNsReg对象
/* read only map, init */
var pluginregister pluginRegister
type PluginRegisterData struct {
Client IPluginRegister
Ns IPluginRegister
Thread IPluginRegister
}
type pluginRegister struct {
M map[string]PluginRegisterData
}
func init() {
if runtime.NumGoroutine() != 1 {
panic(" NumGoroutine() should be 1 on init time, require lock ")
}
pluginregister.M = make(map[string]PluginRegisterData)
}
PluginRegister负责注册各个协议插件,以arp协议为例:
/* register of plugins callbacks for ns,c level */
core.PluginRegister(ARP_PLUG,
core.PluginRegisterData{Client: PluginArpCReg{},
Ns: PluginArpNsReg{},
Thread: nil}) /* no need for thread context for now */
// core.PluginRegister
// PluginRegister register per plugin 3 level information
func PluginRegister(pi string, pr PluginRegisterData) {
...
fmt.Sprintf(" register plugin %s ", pi)
pluginregister.M[pi] = pr
}
RegisterCB负责将具体的功能函数注册到rpc处理框架中, 如以arp协议为例core.RegisterCB("arp_ns_set_cfg", ApiArpNsSetCfgHandler{}, true)
func RegisterCB(method string, h jsonrpc.Handler, noApi bool) {
method_repo = append(method_repo, cRpcMethodRec{method, h, noApi})
}
// NewZmqRpc create a zmq server in port
func (o *CZmqJsonRPC2) NewZmqRpc(serverPort uint16, simulation bool) {
...
mr := jsonrpc.NewMethodRepository()
o.mr = mr
o.mr.Verbose = false
for _, rec := range method_repo {
...
if err := mr.RegisterMethod(rec.method, rec.h, noApi); err != nil {
log.Fatalln(err)
}
}
}
ParserRegister注册处理协议相关数据的函数,以arp协议为例,当收到arp数据包时,调用函数HandleRxArpPacket处理相应数据报文
/* register callback for rx side*/
core.ParserRegister("arp", HandleRxArpPacket)
type parserProtocols struct {
M map[string]ParserCb
}
var parserDb parserProtocols
func getProto(proto string) ParserCb {
...
return parserDb.M[proto]
}
func ParserRegister(proto string, cb ParserCb) {
...
fmt.Sprintf(" register protocol %s ", proto)
parserDb.M[proto] = cb
}
协议Register函数将各个协议通过ParserRegister注册的处理函数,通过RegisterParserCb函数将协议处理函数对应到Parser对象中的各个协议处理函数;
以arp协议为例
func RegisterPlugins(tctx *core.CThreadCtx) {
// These are ordered alphabetically, just like in the imports.
appsim.Register(tctx)
arp.Register(tctx)
...
}
// arp.Register
func Register(ctx *core.CThreadCtx) {
ctx.RegisterParserCb("arp")
}
func (o *CThreadCtx) RegisterParserCb(protocol string) {
o.parser.Register(protocol)
}
/* counters */
type Parser struct {
tctx *CThreadCtx
stats ParserStats
/* call backs */
arp ParserCb
....
}
func (o *Parser) Register(protocol string) {
if protocol == "arp" {
o.arp = getProto("arp")
}
...
}