aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/arp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r--net/ipv4/arp.c36
1 files changed, 14 insertions, 22 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 04c8b69fd426..090d273d7865 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -433,14 +433,13 @@ static int arp_ignore(struct in_device *in_dev, __be32 sip, __be32 tip)
433 433
434static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) 434static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev)
435{ 435{
436 struct flowi fl = { .fl4_dst = sip,
437 .fl4_src = tip };
438 struct rtable *rt; 436 struct rtable *rt;
439 int flag = 0; 437 int flag = 0;
440 /*unsigned long now; */ 438 /*unsigned long now; */
441 struct net *net = dev_net(dev); 439 struct net *net = dev_net(dev);
442 440
443 if (ip_route_output_key(net, &rt, &fl) < 0) 441 rt = ip_route_output(net, sip, tip, 0, 0);
442 if (IS_ERR(rt))
444 return 1; 443 return 1;
445 if (rt->dst.dev != dev) { 444 if (rt->dst.dev != dev) {
446 NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER); 445 NET_INC_STATS_BH(net, LINUX_MIB_ARPFILTER);
@@ -1017,14 +1016,13 @@ static int arp_req_set_proxy(struct net *net, struct net_device *dev, int on)
1017 IPV4_DEVCONF_ALL(net, PROXY_ARP) = on; 1016 IPV4_DEVCONF_ALL(net, PROXY_ARP) = on;
1018 return 0; 1017 return 0;
1019 } 1018 }
1020 if (__in_dev_get_rcu(dev)) { 1019 if (__in_dev_get_rtnl(dev)) {
1021 IN_DEV_CONF_SET(__in_dev_get_rcu(dev), PROXY_ARP, on); 1020 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, on);
1022 return 0; 1021 return 0;
1023 } 1022 }
1024 return -ENXIO; 1023 return -ENXIO;
1025} 1024}
1026 1025
1027/* must be called with rcu_read_lock() */
1028static int arp_req_set_public(struct net *net, struct arpreq *r, 1026static int arp_req_set_public(struct net *net, struct arpreq *r,
1029 struct net_device *dev) 1027 struct net_device *dev)
1030{ 1028{
@@ -1062,12 +1060,10 @@ static int arp_req_set(struct net *net, struct arpreq *r,
1062 if (r->arp_flags & ATF_PERM) 1060 if (r->arp_flags & ATF_PERM)
1063 r->arp_flags |= ATF_COM; 1061 r->arp_flags |= ATF_COM;
1064 if (dev == NULL) { 1062 if (dev == NULL) {
1065 struct flowi fl = { .fl4_dst = ip, 1063 struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0);
1066 .fl4_tos = RTO_ONLINK }; 1064
1067 struct rtable *rt; 1065 if (IS_ERR(rt))
1068 err = ip_route_output_key(net, &rt, &fl); 1066 return PTR_ERR(rt);
1069 if (err != 0)
1070 return err;
1071 dev = rt->dst.dev; 1067 dev = rt->dst.dev;
1072 ip_rt_put(rt); 1068 ip_rt_put(rt);
1073 if (!dev) 1069 if (!dev)
@@ -1178,7 +1174,6 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r,
1178static int arp_req_delete(struct net *net, struct arpreq *r, 1174static int arp_req_delete(struct net *net, struct arpreq *r,
1179 struct net_device *dev) 1175 struct net_device *dev)
1180{ 1176{
1181 int err;
1182 __be32 ip; 1177 __be32 ip;
1183 1178
1184 if (r->arp_flags & ATF_PUBL) 1179 if (r->arp_flags & ATF_PUBL)
@@ -1186,12 +1181,9 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
1186 1181
1187 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; 1182 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
1188 if (dev == NULL) { 1183 if (dev == NULL) {
1189 struct flowi fl = { .fl4_dst = ip, 1184 struct rtable *rt = ip_route_output(net, ip, 0, RTO_ONLINK, 0);
1190 .fl4_tos = RTO_ONLINK }; 1185 if (IS_ERR(rt))
1191 struct rtable *rt; 1186 return PTR_ERR(rt);
1192 err = ip_route_output_key(net, &rt, &fl);
1193 if (err != 0)
1194 return err;
1195 dev = rt->dst.dev; 1187 dev = rt->dst.dev;
1196 ip_rt_put(rt); 1188 ip_rt_put(rt);
1197 if (!dev) 1189 if (!dev)
@@ -1233,10 +1225,10 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
1233 if (!(r.arp_flags & ATF_NETMASK)) 1225 if (!(r.arp_flags & ATF_NETMASK))
1234 ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr = 1226 ((struct sockaddr_in *)&r.arp_netmask)->sin_addr.s_addr =
1235 htonl(0xFFFFFFFFUL); 1227 htonl(0xFFFFFFFFUL);
1236 rcu_read_lock(); 1228 rtnl_lock();
1237 if (r.arp_dev[0]) { 1229 if (r.arp_dev[0]) {
1238 err = -ENODEV; 1230 err = -ENODEV;
1239 dev = dev_get_by_name_rcu(net, r.arp_dev); 1231 dev = __dev_get_by_name(net, r.arp_dev);
1240 if (dev == NULL) 1232 if (dev == NULL)
1241 goto out; 1233 goto out;
1242 1234
@@ -1263,7 +1255,7 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
1263 break; 1255 break;
1264 } 1256 }
1265out: 1257out:
1266 rcu_read_unlock(); 1258 rtnl_unlock();
1267 if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r))) 1259 if (cmd == SIOCGARP && !err && copy_to_user(arg, &r, sizeof(r)))
1268 err = -EFAULT; 1260 err = -EFAULT;
1269 return err; 1261 return err;