aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/arp.c58
1 files changed, 33 insertions, 25 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c
index 54a76b8b803a..04e0ecdd07be 100644
--- a/net/ipv4/arp.c
+++ b/net/ipv4/arp.c
@@ -952,37 +952,45 @@ out_of_mem:
952 * Set (create) an ARP cache entry. 952 * Set (create) an ARP cache entry.
953 */ 953 */
954 954
955static int arp_req_set_public(struct arpreq *r, struct net_device *dev)
956{
957 __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
958 __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr;
959
960 if (mask && mask != htonl(0xFFFFFFFF))
961 return -EINVAL;
962 if (!dev && (r->arp_flags & ATF_COM)) {
963 dev = dev_getbyhwaddr(&init_net, r->arp_ha.sa_family,
964 r->arp_ha.sa_data);
965 if (!dev)
966 return -ENODEV;
967 }
968 if (mask) {
969 if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)
970 return -ENOBUFS;
971 return 0;
972 }
973 if (dev == NULL) {
974 IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
975 return 0;
976 }
977 if (__in_dev_get_rtnl(dev)) {
978 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
979 return 0;
980 }
981 return -ENXIO;
982}
983
955static int arp_req_set(struct arpreq *r, struct net_device * dev) 984static int arp_req_set(struct arpreq *r, struct net_device * dev)
956{ 985{
957 __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr; 986 __be32 ip;
958 struct neighbour *neigh; 987 struct neighbour *neigh;
959 int err; 988 int err;
960 989
961 if (r->arp_flags&ATF_PUBL) { 990 if (r->arp_flags & ATF_PUBL)
962 __be32 mask = ((struct sockaddr_in *) &r->arp_netmask)->sin_addr.s_addr; 991 return arp_req_set_public(r, dev);
963 if (mask && mask != htonl(0xFFFFFFFF))
964 return -EINVAL;
965 if (!dev && (r->arp_flags & ATF_COM)) {
966 dev = dev_getbyhwaddr(&init_net, r->arp_ha.sa_family, r->arp_ha.sa_data);
967 if (!dev)
968 return -ENODEV;
969 }
970 if (mask) {
971 if (pneigh_lookup(&arp_tbl, &ip, dev, 1) == NULL)
972 return -ENOBUFS;
973 return 0;
974 }
975 if (dev == NULL) {
976 IPV4_DEVCONF_ALL(PROXY_ARP) = 1;
977 return 0;
978 }
979 if (__in_dev_get_rtnl(dev)) {
980 IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), PROXY_ARP, 1);
981 return 0;
982 }
983 return -ENXIO;
984 }
985 992
993 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr;
986 if (r->arp_flags & ATF_PERM) 994 if (r->arp_flags & ATF_PERM)
987 r->arp_flags |= ATF_COM; 995 r->arp_flags |= ATF_COM;
988 if (dev == NULL) { 996 if (dev == NULL) {