On Thu, Apr 04, 2019 at 10:50:00AM -0700, David Ahern wrote:
> From: David Ahern <dsah...@gmail.com>
> 
> A common them in the output path is looking up a neigh entry for a

s/them/theme/

> nexthop, either the gateway in an rtable or a fallback to the daddr
> in the skb:
> 
>         nexthop = (__force u32)rt_nexthop(rt, ip_hdr(skb)->daddr);
>         neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
>         if (unlikely(!neigh))
>                 neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
> 
> To allow the nexthop to be an IPv6 address we need to consider the
> family of the nexthop and then call __ipv*_neigh_lookup_noref based
> on it.
> 
> To make this simpler, add a ip_neigh_gw4 helper similar to ip_neigh_gw6
> which handles:
> 
>         neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
>         if (unlikely(!neigh))
>                 neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
> 
> And then add a second one, ip_neigh_for_gw, that calls either
> ip_neigh_gw4 or ip_neigh_gw6 based on the address family of the gateway.
> 
> Update the output paths in the VRF driver and core v4 code to use
> ip_neigh_for_gw simplifying the family based lookup and making both
> ready for a v6 nexthop.
> 
> ipv4_neigh_lookup has a different need - the potential to resolve a
> passed in address in addition to any gateway in the rtable or skb. Since
> this is a one-off, add ip_neigh_gw4 and ip_neigh_gw6 diectly. The
> difference between __neigh_create used by the helpers and neigh_create
> called by ipv4_neigh_lookup is taking a refcount, so add rcu_read_lock_bh
> and bump the refcnt on the neigh entry.
> 
> Signed-off-by: David Ahern <dsah...@gmail.com>

Looks good to me. A couple of nits below.

> @@ -572,13 +572,11 @@ static int vrf_finish_output(struct net *net, struct 
> sock *sk, struct sk_buff *s
>  
>       rcu_read_lock_bh();
>  
> -     nexthop = (__force u32)rt_nexthop(rt, ip_hdr(skb)->daddr);
> -     neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
> -     if (unlikely(!neigh))
> -             neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
> +     neigh = ip_neigh_for_gw(rt, skb, &is_v6gw);
>       if (!IS_ERR(neigh)) {
>               sock_confirm_neigh(skb, neigh);
> -             ret = neigh_output(neigh, skb, false);
> +             /* if crossing protocols, can not used the cached header */

s/used/use/

> +             ret = neigh_output(neigh, skb, is_v6gw);
>               rcu_read_unlock_bh();
>               return ret;
>       }

...

> @@ -218,16 +218,13 @@ static int ip_finish_output2(struct net *net, struct 
> sock *sk, struct sk_buff *s
>       }
>  
>       rcu_read_lock_bh();
> -     nexthop = (__force u32) rt_nexthop(rt, ip_hdr(skb)->daddr);
> -     neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
> -     if (unlikely(!neigh))
> -             neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
> +     neigh = ip_neigh_for_gw(rt, skb, &is_v6gw);
>       if (!IS_ERR(neigh)) {
>               int res;
>  
>               sock_confirm_neigh(skb, neigh);
> -             res = neigh_output(neigh, skb, false);
> -
> +             /* if crossing protocols, can not used the cached header */

s/used/use/

> +             res = neigh_output(neigh, skb, is_v6gw);
>               rcu_read_unlock_bh();
>               return res;
>       }

Reply via email to