diff options
Diffstat (limited to 'net/ipv4/arp.c')
| -rw-r--r-- | net/ipv4/arp.c | 36 |
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 | ||
| 434 | static int arp_filter(__be32 sip, __be32 tip, struct net_device *dev) | 434 | static 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() */ | ||
| 1028 | static int arp_req_set_public(struct net *net, struct arpreq *r, | 1026 | static 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, | |||
| 1178 | static int arp_req_delete(struct net *net, struct arpreq *r, | 1174 | static 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 | } |
| 1265 | out: | 1257 | out: |
| 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; |
