Bug 1357598

Summary: Set /proc/sys/net/bridge/bridge-nf-call-arptables to zero
Product: Red Hat OpenStack Reporter: Phil Sutter <psutter>
Component: openstack-neutronAssignee: Ihar Hrachyshka <ihrachys>
Status: CLOSED NEXTRELEASE QA Contact: Toni Freger <tfreger>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: unspecifiedCC: amuller, beagles, chrisw, ihrachys, majopela, nyechiel, rkhan, srevivo
Target Milestone: ---Keywords: ZStream
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2017-04-05 19:44:56 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Phil Sutter 2016-07-18 15:32:51 UTC
The procfs files /proc/sys/net/bridge/bridge-nf-call-* control whether
iptables sees packets being forwarded by linux bridges. Since neither Compute
nor Network nodes in an OpenStack setup contain any arptables rules, it is not
necessary to pass ARP packets to it.

Here's the relevant kernel code:

static unsigned int br_nf_forward_arp(void *priv,
                                      struct sk_buff *skb,
                                      const struct nf_hook_state *state)
{
        struct net_bridge_port *p;
        struct net_bridge *br;
        struct net_device **d = (struct net_device **)(skb->cb);

        p = br_port_get_rcu(state->out);
        if (p == NULL)
                return NF_ACCEPT;
        br = p->br;

        if (!brnf_call_arptables && !br->nf_call_arptables)
                return NF_ACCEPT;

        if (!IS_ARP(skb)) {
                if (!IS_VLAN_ARP(skb))
                        return NF_ACCEPT;
                nf_bridge_pull_encap_header(skb);
        }

        if (arp_hdr(skb)->ar_pln != 4) {
                if (IS_VLAN_ARP(skb))
                        nf_bridge_push_encap_header(skb);
                return NF_ACCEPT;
        }
        *d = state->in;
        NF_HOOK(NFPROTO_ARP, NF_ARP_FORWARD, state->net, state->sk, skb,
                state->in, state->out, br_nf_forward_finish);

        return NF_STOLEN;
}

The value of /proc/sys/net/bridge/bridge-nf-call-arptables is reflected in
brnf_call_arptables variable. So unless the setting is enabled on a per-bridge
basis, setting it to zero will eliminate the IS_ARP() check for every packet
passing the bridge and a few more checks including the NF_HOOK() call for
every ARP packet passing by.

Per packet, I expect a very small performance improvement here. On a larger
scale, thinking of ARP broadcasts this might reduce the system's base load
considerably. Also, it's a very simple change and guaranteed to be safe since
OSP doesn't even require arptables to be present on any of the systems it is
deployed on.

Comment 2 Miguel Angel Ajo 2016-07-19 12:18:17 UTC
I've checked the installers don't set that currently, so it's only on the neutron side :)

Comment 3 Assaf Muller 2017-04-05 19:44:56 UTC
The fix is available in upstream stable/ocata, master.