aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/fib_frontend.c2
-rw-r--r--net/ipv4/fib_semantics.c1
-rw-r--r--net/ipv4/ip_output.c16
-rw-r--r--net/ipv4/ip_tunnel.c17
-rw-r--r--net/ipv4/ip_tunnel_core.c4
-rw-r--r--net/ipv4/ipmr.c2
-rw-r--r--net/ipv4/netfilter/ipt_rpfilter.c5
-rw-r--r--net/ipv4/ping.c15
-rw-r--r--net/ipv4/route.c9
-rw-r--r--net/ipv4/tcp_output.c2
-rw-r--r--net/ipv4/xfrm4_output.c2
11 files changed, 39 insertions, 36 deletions
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index 1a629f870274..255aa9946fe7 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -250,7 +250,7 @@ static int __fib_validate_source(struct sk_buff *skb, __be32 src, __be32 dst,
250 bool dev_match; 250 bool dev_match;
251 251
252 fl4.flowi4_oif = 0; 252 fl4.flowi4_oif = 0;
253 fl4.flowi4_iif = oif; 253 fl4.flowi4_iif = oif ? : LOOPBACK_IFINDEX;
254 fl4.daddr = src; 254 fl4.daddr = src;
255 fl4.saddr = dst; 255 fl4.saddr = dst;
256 fl4.flowi4_tos = tos; 256 fl4.flowi4_tos = tos;
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index b53f0bf84dca..8a043f03c88e 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -631,6 +631,7 @@ static int fib_check_nh(struct fib_config *cfg, struct fib_info *fi,
631 .daddr = nh->nh_gw, 631 .daddr = nh->nh_gw,
632 .flowi4_scope = cfg->fc_scope + 1, 632 .flowi4_scope = cfg->fc_scope + 1,
633 .flowi4_oif = nh->nh_oif, 633 .flowi4_oif = nh->nh_oif,
634 .flowi4_iif = LOOPBACK_IFINDEX,
634 }; 635 };
635 636
636 /* It is not necessary, but requires a bit of thinking */ 637 /* It is not necessary, but requires a bit of thinking */
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 1a0755fea491..1cbeba5edff9 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -101,17 +101,17 @@ int __ip_local_out(struct sk_buff *skb)
101 skb_dst(skb)->dev, dst_output); 101 skb_dst(skb)->dev, dst_output);
102} 102}
103 103
104int ip_local_out(struct sk_buff *skb) 104int ip_local_out_sk(struct sock *sk, struct sk_buff *skb)
105{ 105{
106 int err; 106 int err;
107 107
108 err = __ip_local_out(skb); 108 err = __ip_local_out(skb);
109 if (likely(err == 1)) 109 if (likely(err == 1))
110 err = dst_output(skb); 110 err = dst_output_sk(sk, skb);
111 111
112 return err; 112 return err;
113} 113}
114EXPORT_SYMBOL_GPL(ip_local_out); 114EXPORT_SYMBOL_GPL(ip_local_out_sk);
115 115
116static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst) 116static inline int ip_select_ttl(struct inet_sock *inet, struct dst_entry *dst)
117{ 117{
@@ -226,9 +226,8 @@ static int ip_finish_output(struct sk_buff *skb)
226 return ip_finish_output2(skb); 226 return ip_finish_output2(skb);
227} 227}
228 228
229int ip_mc_output(struct sk_buff *skb) 229int ip_mc_output(struct sock *sk, struct sk_buff *skb)
230{ 230{
231 struct sock *sk = skb->sk;
232 struct rtable *rt = skb_rtable(skb); 231 struct rtable *rt = skb_rtable(skb);
233 struct net_device *dev = rt->dst.dev; 232 struct net_device *dev = rt->dst.dev;
234 233
@@ -287,7 +286,7 @@ int ip_mc_output(struct sk_buff *skb)
287 !(IPCB(skb)->flags & IPSKB_REROUTED)); 286 !(IPCB(skb)->flags & IPSKB_REROUTED));
288} 287}
289 288
290int ip_output(struct sk_buff *skb) 289int ip_output(struct sock *sk, struct sk_buff *skb)
291{ 290{
292 struct net_device *dev = skb_dst(skb)->dev; 291 struct net_device *dev = skb_dst(skb)->dev;
293 292
@@ -315,9 +314,9 @@ static void ip_copy_addrs(struct iphdr *iph, const struct flowi4 *fl4)
315 sizeof(fl4->saddr) + sizeof(fl4->daddr)); 314 sizeof(fl4->saddr) + sizeof(fl4->daddr));
316} 315}
317 316
318int ip_queue_xmit(struct sk_buff *skb, struct flowi *fl) 317/* Note: skb->sk can be different from sk, in case of tunnels */
318int ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl)
319{ 319{
320 struct sock *sk = skb->sk;
321 struct inet_sock *inet = inet_sk(sk); 320 struct inet_sock *inet = inet_sk(sk);
322 struct ip_options_rcu *inet_opt; 321 struct ip_options_rcu *inet_opt;
323 struct flowi4 *fl4; 322 struct flowi4 *fl4;
@@ -389,6 +388,7 @@ packet_routed:
389 ip_select_ident_more(skb, &rt->dst, sk, 388 ip_select_ident_more(skb, &rt->dst, sk,
390 (skb_shinfo(skb)->gso_segs ?: 1) - 1); 389 (skb_shinfo(skb)->gso_segs ?: 1) - 1);
391 390
391 /* TODO : should we use skb->sk here instead of sk ? */
392 skb->priority = sk->sk_priority; 392 skb->priority = sk->sk_priority;
393 skb->mark = sk->sk_mark; 393 skb->mark = sk->sk_mark;
394 394
diff --git a/net/ipv4/ip_tunnel.c b/net/ipv4/ip_tunnel.c
index e77381d1df9a..fa5b7519765f 100644
--- a/net/ipv4/ip_tunnel.c
+++ b/net/ipv4/ip_tunnel.c
@@ -670,7 +670,7 @@ void ip_tunnel_xmit(struct sk_buff *skb, struct net_device *dev,
670 return; 670 return;
671 } 671 }
672 672
673 err = iptunnel_xmit(rt, skb, fl4.saddr, fl4.daddr, protocol, 673 err = iptunnel_xmit(skb->sk, rt, skb, fl4.saddr, fl4.daddr, protocol,
674 tos, ttl, df, !net_eq(tunnel->net, dev_net(dev))); 674 tos, ttl, df, !net_eq(tunnel->net, dev_net(dev)));
675 iptunnel_xmit_stats(err, &dev->stats, dev->tstats); 675 iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
676 676
@@ -722,19 +722,18 @@ static void ip_tunnel_update(struct ip_tunnel_net *itn,
722int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd) 722int ip_tunnel_ioctl(struct net_device *dev, struct ip_tunnel_parm *p, int cmd)
723{ 723{
724 int err = 0; 724 int err = 0;
725 struct ip_tunnel *t; 725 struct ip_tunnel *t = netdev_priv(dev);
726 struct net *net = dev_net(dev); 726 struct net *net = t->net;
727 struct ip_tunnel *tunnel = netdev_priv(dev); 727 struct ip_tunnel_net *itn = net_generic(net, t->ip_tnl_net_id);
728 struct ip_tunnel_net *itn = net_generic(net, tunnel->ip_tnl_net_id);
729 728
730 BUG_ON(!itn->fb_tunnel_dev); 729 BUG_ON(!itn->fb_tunnel_dev);
731 switch (cmd) { 730 switch (cmd) {
732 case SIOCGETTUNNEL: 731 case SIOCGETTUNNEL:
733 t = NULL; 732 if (dev == itn->fb_tunnel_dev) {
734 if (dev == itn->fb_tunnel_dev)
735 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type); 733 t = ip_tunnel_find(itn, p, itn->fb_tunnel_dev->type);
736 if (t == NULL) 734 if (t == NULL)
737 t = netdev_priv(dev); 735 t = netdev_priv(dev);
736 }
738 memcpy(p, &t->parms, sizeof(*p)); 737 memcpy(p, &t->parms, sizeof(*p));
739 break; 738 break;
740 739
diff --git a/net/ipv4/ip_tunnel_core.c b/net/ipv4/ip_tunnel_core.c
index e0c2b1d2ea4e..bcf206c79005 100644
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -46,7 +46,7 @@
46#include <net/netns/generic.h> 46#include <net/netns/generic.h>
47#include <net/rtnetlink.h> 47#include <net/rtnetlink.h>
48 48
49int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb, 49int iptunnel_xmit(struct sock *sk, struct rtable *rt, struct sk_buff *skb,
50 __be32 src, __be32 dst, __u8 proto, 50 __be32 src, __be32 dst, __u8 proto,
51 __u8 tos, __u8 ttl, __be16 df, bool xnet) 51 __u8 tos, __u8 ttl, __be16 df, bool xnet)
52{ 52{
@@ -76,7 +76,7 @@ int iptunnel_xmit(struct rtable *rt, struct sk_buff *skb,
76 iph->ttl = ttl; 76 iph->ttl = ttl;
77 __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1); 77 __ip_select_ident(iph, &rt->dst, (skb_shinfo(skb)->gso_segs ?: 1) - 1);
78 78
79 err = ip_local_out(skb); 79 err = ip_local_out_sk(sk, skb);
80 if (unlikely(net_xmit_eval(err))) 80 if (unlikely(net_xmit_eval(err)))
81 pkt_len = 0; 81 pkt_len = 0;
82 return pkt_len; 82 return pkt_len;
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 28863570dd60..d84dc8d4c916 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -455,7 +455,7 @@ static netdev_tx_t reg_vif_xmit(struct sk_buff *skb, struct net_device *dev)
455 struct mr_table *mrt; 455 struct mr_table *mrt;
456 struct flowi4 fl4 = { 456 struct flowi4 fl4 = {
457 .flowi4_oif = dev->ifindex, 457 .flowi4_oif = dev->ifindex,
458 .flowi4_iif = skb->skb_iif, 458 .flowi4_iif = skb->skb_iif ? : LOOPBACK_IFINDEX,
459 .flowi4_mark = skb->mark, 459 .flowi4_mark = skb->mark,
460 }; 460 };
461 int err; 461 int err;
diff --git a/net/ipv4/netfilter/ipt_rpfilter.c b/net/ipv4/netfilter/ipt_rpfilter.c
index c49dcd0284a0..4bfaedf9b34e 100644
--- a/net/ipv4/netfilter/ipt_rpfilter.c
+++ b/net/ipv4/netfilter/ipt_rpfilter.c
@@ -89,11 +89,8 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par)
89 if (ipv4_is_multicast(iph->daddr)) { 89 if (ipv4_is_multicast(iph->daddr)) {
90 if (ipv4_is_zeronet(iph->saddr)) 90 if (ipv4_is_zeronet(iph->saddr))
91 return ipv4_is_local_multicast(iph->daddr) ^ invert; 91 return ipv4_is_local_multicast(iph->daddr) ^ invert;
92 flow.flowi4_iif = 0;
93 } else {
94 flow.flowi4_iif = LOOPBACK_IFINDEX;
95 } 92 }
96 93 flow.flowi4_iif = LOOPBACK_IFINDEX;
97 flow.daddr = iph->saddr; 94 flow.daddr = iph->saddr;
98 flow.saddr = rpfilter_get_saddr(iph->daddr); 95 flow.saddr = rpfilter_get_saddr(iph->daddr);
99 flow.flowi4_oif = 0; 96 flow.flowi4_oif = 0;
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
index f4b19e5dde54..8210964a9f19 100644
--- a/net/ipv4/ping.c
+++ b/net/ipv4/ping.c
@@ -252,26 +252,33 @@ int ping_init_sock(struct sock *sk)
252{ 252{
253 struct net *net = sock_net(sk); 253 struct net *net = sock_net(sk);
254 kgid_t group = current_egid(); 254 kgid_t group = current_egid();
255 struct group_info *group_info = get_current_groups(); 255 struct group_info *group_info;
256 int i, j, count = group_info->ngroups; 256 int i, j, count;
257 kgid_t low, high; 257 kgid_t low, high;
258 int ret = 0;
258 259
259 inet_get_ping_group_range_net(net, &low, &high); 260 inet_get_ping_group_range_net(net, &low, &high);
260 if (gid_lte(low, group) && gid_lte(group, high)) 261 if (gid_lte(low, group) && gid_lte(group, high))
261 return 0; 262 return 0;
262 263
264 group_info = get_current_groups();
265 count = group_info->ngroups;
263 for (i = 0; i < group_info->nblocks; i++) { 266 for (i = 0; i < group_info->nblocks; i++) {
264 int cp_count = min_t(int, NGROUPS_PER_BLOCK, count); 267 int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
265 for (j = 0; j < cp_count; j++) { 268 for (j = 0; j < cp_count; j++) {
266 kgid_t gid = group_info->blocks[i][j]; 269 kgid_t gid = group_info->blocks[i][j];
267 if (gid_lte(low, gid) && gid_lte(gid, high)) 270 if (gid_lte(low, gid) && gid_lte(gid, high))
268 return 0; 271 goto out_release_group;
269 } 272 }
270 273
271 count -= cp_count; 274 count -= cp_count;
272 } 275 }
273 276
274 return -EACCES; 277 ret = -EACCES;
278
279out_release_group:
280 put_group_info(group_info);
281 return ret;
275} 282}
276EXPORT_SYMBOL_GPL(ping_init_sock); 283EXPORT_SYMBOL_GPL(ping_init_sock);
277 284
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 34d094cadb11..db1e0da871f4 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1129,7 +1129,7 @@ static void ipv4_link_failure(struct sk_buff *skb)
1129 dst_set_expires(&rt->dst, 0); 1129 dst_set_expires(&rt->dst, 0);
1130} 1130}
1131 1131
1132static int ip_rt_bug(struct sk_buff *skb) 1132static int ip_rt_bug(struct sock *sk, struct sk_buff *skb)
1133{ 1133{
1134 pr_debug("%s: %pI4 -> %pI4, %s\n", 1134 pr_debug("%s: %pI4 -> %pI4, %s\n",
1135 __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, 1135 __func__, &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr,
@@ -1700,8 +1700,7 @@ static int ip_route_input_slow(struct sk_buff *skb, __be32 daddr, __be32 saddr,
1700 1700
1701 if (res.type == RTN_LOCAL) { 1701 if (res.type == RTN_LOCAL) {
1702 err = fib_validate_source(skb, saddr, daddr, tos, 1702 err = fib_validate_source(skb, saddr, daddr, tos,
1703 LOOPBACK_IFINDEX, 1703 0, dev, in_dev, &itag);
1704 dev, in_dev, &itag);
1705 if (err < 0) 1704 if (err < 0)
1706 goto martian_source_keep_err; 1705 goto martian_source_keep_err;
1707 goto local_input; 1706 goto local_input;
@@ -2218,7 +2217,7 @@ struct dst_entry *ipv4_blackhole_route(struct net *net, struct dst_entry *dst_or
2218 2217
2219 new->__use = 1; 2218 new->__use = 1;
2220 new->input = dst_discard; 2219 new->input = dst_discard;
2221 new->output = dst_discard; 2220 new->output = dst_discard_sk;
2222 2221
2223 new->dev = ort->dst.dev; 2222 new->dev = ort->dst.dev;
2224 if (new->dev) 2223 if (new->dev)
@@ -2357,7 +2356,7 @@ static int rt_fill_info(struct net *net, __be32 dst, __be32 src,
2357 } 2356 }
2358 } else 2357 } else
2359#endif 2358#endif
2360 if (nla_put_u32(skb, RTA_IIF, rt->rt_iif)) 2359 if (nla_put_u32(skb, RTA_IIF, skb->dev->ifindex))
2361 goto nla_put_failure; 2360 goto nla_put_failure;
2362 } 2361 }
2363 2362
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 699fb102e971..025e25093984 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -981,7 +981,7 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
981 TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS, 981 TCP_ADD_STATS(sock_net(sk), TCP_MIB_OUTSEGS,
982 tcp_skb_pcount(skb)); 982 tcp_skb_pcount(skb));
983 983
984 err = icsk->icsk_af_ops->queue_xmit(skb, &inet->cork.fl); 984 err = icsk->icsk_af_ops->queue_xmit(sk, skb, &inet->cork.fl);
985 if (likely(err <= 0)) 985 if (likely(err <= 0))
986 return err; 986 return err;
987 987
diff --git a/net/ipv4/xfrm4_output.c b/net/ipv4/xfrm4_output.c
index baa0f63731fd..40e701f2e1e0 100644
--- a/net/ipv4/xfrm4_output.c
+++ b/net/ipv4/xfrm4_output.c
@@ -86,7 +86,7 @@ int xfrm4_output_finish(struct sk_buff *skb)
86 return xfrm_output(skb); 86 return xfrm_output(skb);
87} 87}
88 88
89int xfrm4_output(struct sk_buff *skb) 89int xfrm4_output(struct sock *sk, struct sk_buff *skb)
90{ 90{
91 struct dst_entry *dst = skb_dst(skb); 91 struct dst_entry *dst = skb_dst(skb);
92 struct xfrm_state *x = dst->xfrm; 92 struct xfrm_state *x = dst->xfrm;