Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 03 Jan 2015 15:00:57 +0300
From:      "Alexander V. Chernikov" <melifaro@yandex-team.ru>
To:        Luigi Rizzo <rizzo@iet.unipi.it>
Cc:        "freebsd-net@freebsd.org" <freebsd-net@freebsd.org>
Subject:   Re: host pipes and netmap 'emulated mode'
Message-ID:  <54A7D9F9.5080206@yandex-team.ru>
In-Reply-To: <20150102164559.GA68836@onelab2.iet.unipi.it>
References:  <54A6BAE0.9020404@yandex-team.ru> <20150102164559.GA68836@onelab2.iet.unipi.it>

next in thread | previous in thread | raw e-mail | index | archive | help
On 02.01.2015 19:45, Luigi Rizzo wrote:
> On Fri, Jan 02, 2015 at 06:36:00PM +0300, Alexander V. Chernikov wrote:
>> Hello list.
>>
>> It looks like it is impossible to use host pipes and emulated netmap
>> mode in some cases.
>>
>> For example, if you're doing something like what traditional router do:
>> packet processing, with kernel-visible logical interfaces, routing
>> daemon running there, you can easily get a panic like this:
>>
>> #0 0xffffffff8094aa76 at kdb_backtrace+0x66
>> #1 0xffffffff809104ee at panic+0x1ce
>> #2 0xffffffff80cf9660 at trap_fatal+0x290
>> #3 0xffffffff80cf99c1 at trap_pfault+0x211
>> #4 0xffffffff80cf9f89 at trap+0x329
>> #5 0xffffffff80ce30d3 at calltrap+0x8
>> #6 0xffffffff809d3b5f at ether_demux+0x6f
>> #7 0xffffffff809d3f34 at ether_nh_input+0x204
>> #8 0xffffffff809dd6d8 at netisr_dispatch_src+0x218
>> #9 0xffffffff8061b2b5 at netmap_send_up+0x35
>> #10 0xffffffff8061b3d7 at netmap_txsync_to_host+0x97
>> #11 0xffffffff8061b400 at netmap_txsync_to_host_compat+0x10
>> #12 0xffffffff8061de8c at netmap_poll+0x2fc
>> #13 0xffffffff807f2313 at devfs_poll_f+0x63
>> #14 0xffffffff8095ea3d at sys_poll+0x35d
>> #15 0xffffffff80cf8e0a at amd64_syscall+0x5ea
>> #16 0xffffffff80ce33b7 at Xfast_syscall+0xf7
>> Uptime: 4m21s
>>
>> The problem here is the following:
>> netmap changes if_input() for the logical network interface and always
>> assumes that generic_rx_handler() is called with netmap-enabled ifp
>> (e.g. original inteface).
>> Unfortunately, there are cases where we have different ifp passed to
>> if_input handler. This particular case is triggered by
>>   (*ifp->if_input)(ifv->ifv_ifp, m);
>> line, where "ifp" represents netmap-enabled NIC, and ifv->ifv_ifp
>> represents vlan subinterface.
>>
>> Then, generic_rx_handler() tries to looking NA/GNA structure but fails
>> since vlan subinterface is not netmap-enabled.
>> So, it looks like that we need a way to call original if_input() but I
>> can't imagine (good) one/
> Surely we can put a check in generic_rx_handler() to make sure that
> NA(ifp) is NULL -- this is already a relatively expensive code
> path so the extra checks won't harm.
Yes, but it would be great if we can recover/call original input
procedure instead of silently dropping frame
>
> But I am a bit unclear on how you trigger this error,
> can you give me more details ?
>
> The offending instruction  (*ifp->if_input)(ifv->ifv_ifp, m)
> is in vlan_input(), so it looks like you are setting the parent
> interface in netmap mode, and (looking at the trace)
> sending packets to the host port.
Yes. Basically, this is "netmap router case" - we configure vlan
interface, bridge interfaces, etc
using kernel interfaces, and propagate some (or all) configuration to
netmap application. It somehow
processes "fast path" traffic and sends control plane traffic to host
via host pipe to handle routing daemon
updates, icmp, fragments, etc..
>
> So i suppose the error path is when netmap_send_up() calls
> the original input handler, NA(ifp)->if_input [i should rename
> the field to something else] which is vlan_input().
>
> I think a proper fix is to make vlan_input() netmap aware,
> and call NA(ifp)->if_input if the interface is in netmap mode.
Well, than we will have to make bridge code netmap aware, netgraph and
tunnel after that.
It seems this is pretty invasive way of doing things.
>
> Otherwise, if vlan_input() is the only case where if_input() is called
> with a different ifp, _and_ the vlan (child) interface has a reference
> to the parent (ifp->parent, though i don't know where this is),
> we can tweak generic_rx_handler() so that it calls
> NA(ifp->parent)->if_input in case NA(ifp) is null.
We will have to add different code for all type of virtual interfaces,
which seems to be better approach.

There is also an option like having per-vnet ifindex-based array with
vlan (and other objects) tracking to get ifp quickly.

What we really lacks here is set_if_input_func() method which can call
some eventhandler so it can be done more generic way
(so, adding glebius@ here)
>
> cheers
> luigi




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?54A7D9F9.5080206>