diff options
Diffstat (limited to 'net/ipv4/arp.c')
-rw-r--r-- | net/ipv4/arp.c | 47 |
1 files changed, 27 insertions, 20 deletions
diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 04e0ecdd07be..e947ad9409b0 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c | |||
@@ -1074,32 +1074,39 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev) | |||
1074 | return err; | 1074 | return err; |
1075 | } | 1075 | } |
1076 | 1076 | ||
1077 | static int arp_req_delete_public(struct arpreq *r, struct net_device *dev) | ||
1078 | { | ||
1079 | __be32 ip = ((struct sockaddr_in *) &r->arp_pa)->sin_addr.s_addr; | ||
1080 | __be32 mask = ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr; | ||
1081 | |||
1082 | if (mask == htonl(0xFFFFFFFF)) | ||
1083 | return pneigh_delete(&arp_tbl, &ip, dev); | ||
1084 | |||
1085 | if (mask == 0) { | ||
1086 | if (dev == NULL) { | ||
1087 | IPV4_DEVCONF_ALL(PROXY_ARP) = 0; | ||
1088 | return 0; | ||
1089 | } | ||
1090 | if (__in_dev_get_rtnl(dev)) { | ||
1091 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), | ||
1092 | PROXY_ARP, 0); | ||
1093 | return 0; | ||
1094 | } | ||
1095 | return -ENXIO; | ||
1096 | } | ||
1097 | return -EINVAL; | ||
1098 | } | ||
1099 | |||
1077 | static int arp_req_delete(struct arpreq *r, struct net_device * dev) | 1100 | static int arp_req_delete(struct arpreq *r, struct net_device * dev) |
1078 | { | 1101 | { |
1079 | int err; | 1102 | int err; |
1080 | __be32 ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; | 1103 | __be32 ip; |
1081 | struct neighbour *neigh; | 1104 | struct neighbour *neigh; |
1082 | 1105 | ||
1083 | if (r->arp_flags & ATF_PUBL) { | 1106 | if (r->arp_flags & ATF_PUBL) |
1084 | __be32 mask = | 1107 | return arp_req_delete_public(r, dev); |
1085 | ((struct sockaddr_in *)&r->arp_netmask)->sin_addr.s_addr; | ||
1086 | if (mask == htonl(0xFFFFFFFF)) | ||
1087 | return pneigh_delete(&arp_tbl, &ip, dev); | ||
1088 | if (mask == 0) { | ||
1089 | if (dev == NULL) { | ||
1090 | IPV4_DEVCONF_ALL(PROXY_ARP) = 0; | ||
1091 | return 0; | ||
1092 | } | ||
1093 | if (__in_dev_get_rtnl(dev)) { | ||
1094 | IN_DEV_CONF_SET(__in_dev_get_rtnl(dev), | ||
1095 | PROXY_ARP, 0); | ||
1096 | return 0; | ||
1097 | } | ||
1098 | return -ENXIO; | ||
1099 | } | ||
1100 | return -EINVAL; | ||
1101 | } | ||
1102 | 1108 | ||
1109 | ip = ((struct sockaddr_in *)&r->arp_pa)->sin_addr.s_addr; | ||
1103 | if (dev == NULL) { | 1110 | if (dev == NULL) { |
1104 | struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, | 1111 | struct flowi fl = { .nl_u = { .ip4_u = { .daddr = ip, |
1105 | .tos = RTO_ONLINK } } }; | 1112 | .tos = RTO_ONLINK } } }; |