summaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-06-28 00:06:39 -0400
committerDavid S. Miller <davem@davemloft.net>2019-06-28 00:06:39 -0400
commitd96ff269a04be286989ead13bf8b4be55bdee8ee (patch)
tree46b6d010a9a4dfe96dc86339d1cbded8874c6b8f /net/ipv4
parent3a49584477ff4c8838833be9f3b7cc13f0f7c0d3 (diff)
parent556e2f6020bf90f63c5dd65e9a2254be6db3185b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
The new route handling in ip_mc_finish_output() from 'net' overlapped with the new support for returning congestion notifications from BPF programs. In order to handle this I had to take the dev_loopback_xmit() calls out of the switch statement. The aquantia driver conflicts were simple overlapping changes. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_output.c25
-rw-r--r--net/ipv4/raw.c2
-rw-r--r--net/ipv4/route.c33
3 files changed, 55 insertions, 5 deletions
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index cdd6c3418b9e..cc7ef0d05bbd 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -327,18 +327,35 @@ static int ip_finish_output(struct net *net, struct sock *sk, struct sk_buff *sk
327static int ip_mc_finish_output(struct net *net, struct sock *sk, 327static int ip_mc_finish_output(struct net *net, struct sock *sk,
328 struct sk_buff *skb) 328 struct sk_buff *skb)
329{ 329{
330 int ret; 330 struct rtable *new_rt;
331 bool do_cn = false;
332 int ret, err;
331 333
332 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb); 334 ret = BPF_CGROUP_RUN_PROG_INET_EGRESS(sk, skb);
333 switch (ret) { 335 switch (ret) {
334 case NET_XMIT_SUCCESS:
335 return dev_loopback_xmit(net, sk, skb);
336 case NET_XMIT_CN: 336 case NET_XMIT_CN:
337 return dev_loopback_xmit(net, sk, skb) ? : ret; 337 do_cn = true;
338 /* fall through */
339 case NET_XMIT_SUCCESS:
340 break;
338 default: 341 default:
339 kfree_skb(skb); 342 kfree_skb(skb);
340 return ret; 343 return ret;
341 } 344 }
345
346 /* Reset rt_iif so that inet_iif() will return skb->skb_iif. Setting
347 * this to non-zero causes ipi_ifindex in in_pktinfo to be overwritten,
348 * see ipv4_pktinfo_prepare().
349 */
350 new_rt = rt_dst_clone(net->loopback_dev, skb_rtable(skb));
351 if (new_rt) {
352 new_rt->rt_iif = 0;
353 skb_dst_drop(skb);
354 skb_dst_set(skb, &new_rt->dst);
355 }
356
357 err = dev_loopback_xmit(net, sk, skb);
358 return (do_cn && err) ? ret : err;
342} 359}
343 360
344int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb) 361int ip_mc_output(struct net *net, struct sock *sk, struct sk_buff *skb)
diff --git a/net/ipv4/raw.c b/net/ipv4/raw.c
index 0b8e06ca75d6..40a6abbc9cf6 100644
--- a/net/ipv4/raw.c
+++ b/net/ipv4/raw.c
@@ -197,7 +197,7 @@ static int raw_v4_input(struct sk_buff *skb, const struct iphdr *iph, int hash)
197 } 197 }
198 sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol, 198 sk = __raw_v4_lookup(net, sk_next(sk), iph->protocol,
199 iph->saddr, iph->daddr, 199 iph->saddr, iph->daddr,
200 skb->dev->ifindex, sdif); 200 dif, sdif);
201 } 201 }
202out: 202out:
203 read_unlock(&raw_v4_hashinfo.lock); 203 read_unlock(&raw_v4_hashinfo.lock);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 59670fafcd26..a3e466b6a60c 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1648,6 +1648,39 @@ struct rtable *rt_dst_alloc(struct net_device *dev,
1648} 1648}
1649EXPORT_SYMBOL(rt_dst_alloc); 1649EXPORT_SYMBOL(rt_dst_alloc);
1650 1650
1651struct rtable *rt_dst_clone(struct net_device *dev, struct rtable *rt)
1652{
1653 struct rtable *new_rt;
1654
1655 new_rt = dst_alloc(&ipv4_dst_ops, dev, 1, DST_OBSOLETE_FORCE_CHK,
1656 rt->dst.flags);
1657
1658 if (new_rt) {
1659 new_rt->rt_genid = rt_genid_ipv4(dev_net(dev));
1660 new_rt->rt_flags = rt->rt_flags;
1661 new_rt->rt_type = rt->rt_type;
1662 new_rt->rt_is_input = rt->rt_is_input;
1663 new_rt->rt_iif = rt->rt_iif;
1664 new_rt->rt_pmtu = rt->rt_pmtu;
1665 new_rt->rt_mtu_locked = rt->rt_mtu_locked;
1666 new_rt->rt_gw_family = rt->rt_gw_family;
1667 if (rt->rt_gw_family == AF_INET)
1668 new_rt->rt_gw4 = rt->rt_gw4;
1669 else if (rt->rt_gw_family == AF_INET6)
1670 new_rt->rt_gw6 = rt->rt_gw6;
1671 INIT_LIST_HEAD(&new_rt->rt_uncached);
1672
1673 new_rt->dst.flags |= DST_HOST;
1674 new_rt->dst.input = rt->dst.input;
1675 new_rt->dst.output = rt->dst.output;
1676 new_rt->dst.error = rt->dst.error;
1677 new_rt->dst.lastuse = jiffies;
1678 new_rt->dst.lwtstate = lwtstate_get(rt->dst.lwtstate);
1679 }
1680 return new_rt;
1681}
1682EXPORT_SYMBOL(rt_dst_clone);
1683
1651/* called in rcu_read_lock() section */ 1684/* called in rcu_read_lock() section */
1652int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr, 1685int ip_mc_validate_source(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1653 u8 tos, struct net_device *dev, 1686 u8 tos, struct net_device *dev,