From: Mahesh Bandewar <mahe...@google.com> netif_receive_skb_core() dispatcher uses skb->dev device to send it to the packet-handlers (e.g. ip_rcv, ipv6_rcv etc). These packet handlers intern use the device passed to determine the net-ns to further process these packets. Now with the nomination logic, the dispatcher will call netif_get_l3_dev() helper to select the device to be used for this processing. Since l3_dev is initialized to self, normal packet processing should not change.
Signed-off-by: Mahesh Bandewar <mahe...@google.com> CC: Eric Dumazet <eduma...@google.com> CC: Tim Hockin <thoc...@google.com> CC: Alex Pollitt <alex.poll...@metaswitch.com> CC: Matthew Dupre <matthew.du...@metaswitch.com> --- net/core/dev.c | 9 ++++++--- net/ipv4/ip_input.c | 5 +++-- net/ipv6/ip6_input.c | 5 +++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/net/core/dev.c b/net/core/dev.c index c4023a68cdc1..9252436ef11a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1811,7 +1811,8 @@ static inline int deliver_skb(struct sk_buff *skb, if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) return -ENOMEM; atomic_inc(&skb->users); - return pt_prev->func(skb, skb->dev, pt_prev, orig_dev); + return pt_prev->func(skb, netif_get_l3_dev(skb->dev), pt_prev, + orig_dev); } static inline void deliver_ptype_list_skb(struct sk_buff *skb, @@ -1904,7 +1905,8 @@ again: } out_unlock: if (pt_prev) - pt_prev->func(skb2, skb->dev, pt_prev, skb->dev); + pt_prev->func(skb2, netif_get_l3_dev(skb->dev), pt_prev, + skb->dev); rcu_read_unlock(); } @@ -4157,7 +4159,8 @@ ncls: if (unlikely(skb_orphan_frags(skb, GFP_ATOMIC))) goto drop; else - ret = pt_prev->func(skb, skb->dev, pt_prev, orig_dev); + ret = pt_prev->func(skb, netif_get_l3_dev(skb->dev), + pt_prev, orig_dev); } else { drop: if (!deliver_exact) diff --git a/net/ipv4/ip_input.c b/net/ipv4/ip_input.c index e3d782746d9d..b47164e3e1c6 100644 --- a/net/ipv4/ip_input.c +++ b/net/ipv4/ip_input.c @@ -247,7 +247,8 @@ int ip_local_deliver(struct sk_buff *skb) /* * Reassemble IP fragments. */ - struct net *net = dev_net(skb->dev); + struct net_device *dev = netif_get_l3_dev(skb->dev); + struct net *net = dev_net(dev); if (ip_is_fragment(ip_hdr(skb))) { if (ip_defrag(net, skb, IP_DEFRAG_LOCAL_DELIVER)) @@ -255,7 +256,7 @@ int ip_local_deliver(struct sk_buff *skb) } return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN, - net, NULL, skb, skb->dev, NULL, + net, NULL, skb, dev, NULL, ip_local_deliver_finish); } diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c index c05c425c2389..88443ac06402 100644 --- a/net/ipv6/ip6_input.c +++ b/net/ipv6/ip6_input.c @@ -287,9 +287,10 @@ discard: int ip6_input(struct sk_buff *skb) { + struct net_device *dev = netif_get_l3_dev(skb->dev); + return NF_HOOK(NFPROTO_IPV6, NF_INET_LOCAL_IN, - dev_net(skb->dev), NULL, skb, skb->dev, NULL, - ip6_input_finish); + dev_net(dev), NULL, skb, dev, NULL, ip6_input_finish); } int ip6_mc_input(struct sk_buff *skb) -- 2.7.0.rc3.207.g0ac5344