Thanks David and Ido, for finding the root-cause for bridge Rx packets getting dropped, also for coming up with a patch.
Regards, Nelson On 9/7/18, 9:09 AM, "David Ahern" <d...@cumulusnetworks.com> wrote: On 9/7/18 9:56 AM, D'Souza, Nelson wrote: > ------------------------------------------------------------------------ > *From:* David Ahern <d...@cumulusnetworks.com> > *Sent:* Thursday, September 6, 2018 5:27 PM > *To:* D'Souza, Nelson; netdev@vger.kernel.org > *Subject:* Re: [**EXTERNAL**] Re: VRF with enslaved L3 enabled bridge > > On 9/5/18 12:00 PM, D'Souza, Nelson wrote: >> Just following up.... would you be able to confirm that this is a > Linux VRF issue? > > I can confirm that I can reproduce the problem. Need to find time to dig > into it. bridge's netfilter hook is dropping the packet. bridge's netfilter code registers hook operations that are invoked when nh_hook is called. It then sees all subsequent calls to nf_hook. Packet wise, the bridge netfilter hook runs first. br_nf_pre_routing allocates nf_bridge, sets in_prerouting to 1 and calls NF_HOOK for NF_INET_PRE_ROUTING. It's finish function, br_nf_pre_routing_finish, then resets in_prerouting flag to 0. Any subsequent calls to nf_hook invoke ip_sabotage_in. That function sees in_prerouting is not set and steals (drops) the packet. The simplest change is to have ip_sabotage_in recognize that the bridge can be enslaved to a VRF (L3 master device) and allow the packet to continue. Thanks to Ido for the hint on ip_sabotage_in. This patch works for me: diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c index 6e0dc6bcd32a..37278dc280eb 100644 --- a/net/bridge/br_netfilter_hooks.c +++ b/net/bridge/br_netfilter_hooks.c @@ -835,7 +835,8 @@ static unsigned int ip_sabotage_in(void *priv, struct sk_buff *skb, const struct nf_hook_state *state) { - if (skb->nf_bridge && !skb->nf_bridge->in_prerouting) { + if (skb->nf_bridge && !skb->nf_bridge->in_prerouting && + !netif_is_l3_master(skb->dev)) { state->okfn(state->net, state->sk, skb); return NF_STOLEN; }