@@ -1003,12 +1003,36 @@ static int arp_rcv(struct sk_buff *skb, struct net_device *dev,
1003
1003
* User level interface (ioctl)
1004
1004
*/
1005
1005
1006
+ static struct net_device * arp_req_dev_by_name (struct net * net , struct arpreq * r )
1007
+ {
1008
+ struct net_device * dev ;
1009
+
1010
+ dev = __dev_get_by_name (net , r -> arp_dev );
1011
+ if (!dev )
1012
+ return ERR_PTR (- ENODEV );
1013
+
1014
+ /* Mmmm... It is wrong... ARPHRD_NETROM == 0 */
1015
+ if (!r -> arp_ha .sa_family )
1016
+ r -> arp_ha .sa_family = dev -> type ;
1017
+
1018
+ if ((r -> arp_flags & ATF_COM ) && r -> arp_ha .sa_family != dev -> type )
1019
+ return ERR_PTR (- EINVAL );
1020
+
1021
+ return dev ;
1022
+ }
1023
+
1006
1024
static struct net_device * arp_req_dev (struct net * net , struct arpreq * r )
1007
1025
{
1008
1026
struct net_device * dev ;
1009
1027
struct rtable * rt ;
1010
1028
__be32 ip ;
1011
1029
1030
+ if (r -> arp_dev [0 ])
1031
+ return arp_req_dev_by_name (net , r );
1032
+
1033
+ if (r -> arp_flags & ATF_PUBL )
1034
+ return NULL ;
1035
+
1012
1036
ip = ((struct sockaddr_in * )& r -> arp_pa )-> sin_addr .s_addr ;
1013
1037
1014
1038
rt = ip_route_output (net , ip , 0 , 0 , 0 , RT_SCOPE_LINK );
@@ -1063,21 +1087,20 @@ static int arp_req_set_public(struct net *net, struct arpreq *r,
1063
1087
return arp_req_set_proxy (net , dev , 1 );
1064
1088
}
1065
1089
1066
- static int arp_req_set (struct net * net , struct arpreq * r ,
1067
- struct net_device * dev )
1090
+ static int arp_req_set (struct net * net , struct arpreq * r )
1068
1091
{
1069
1092
struct neighbour * neigh ;
1093
+ struct net_device * dev ;
1070
1094
__be32 ip ;
1071
1095
int err ;
1072
1096
1097
+ dev = arp_req_dev (net , r );
1098
+ if (IS_ERR (dev ))
1099
+ return PTR_ERR (dev );
1100
+
1073
1101
if (r -> arp_flags & ATF_PUBL )
1074
1102
return arp_req_set_public (net , r , dev );
1075
1103
1076
- if (!dev ) {
1077
- dev = arp_req_dev (net , r );
1078
- if (IS_ERR (dev ))
1079
- return PTR_ERR (dev );
1080
- }
1081
1104
switch (dev -> type ) {
1082
1105
#if IS_ENABLED (CONFIG_FDDI )
1083
1106
case ARPHRD_FDDI :
@@ -1134,10 +1157,18 @@ static unsigned int arp_state_to_flags(struct neighbour *neigh)
1134
1157
* Get an ARP cache entry.
1135
1158
*/
1136
1159
1137
- static int arp_req_get (struct arpreq * r , struct net_device * dev )
1160
+ static int arp_req_get (struct net * net , struct arpreq * r )
1138
1161
{
1139
1162
__be32 ip = ((struct sockaddr_in * ) & r -> arp_pa )-> sin_addr .s_addr ;
1140
1163
struct neighbour * neigh ;
1164
+ struct net_device * dev ;
1165
+
1166
+ if (!r -> arp_dev [0 ])
1167
+ return - ENODEV ;
1168
+
1169
+ dev = arp_req_dev_by_name (net , r );
1170
+ if (IS_ERR (dev ))
1171
+ return PTR_ERR (dev );
1141
1172
1142
1173
neigh = neigh_lookup (& arp_tbl , & ip , dev );
1143
1174
if (!neigh )
@@ -1201,20 +1232,20 @@ static int arp_req_delete_public(struct net *net, struct arpreq *r,
1201
1232
return arp_req_set_proxy (net , dev , 0 );
1202
1233
}
1203
1234
1204
- static int arp_req_delete (struct net * net , struct arpreq * r ,
1205
- struct net_device * dev )
1235
+ static int arp_req_delete (struct net * net , struct arpreq * r )
1206
1236
{
1237
+ struct net_device * dev ;
1207
1238
__be32 ip ;
1208
1239
1240
+ dev = arp_req_dev (net , r );
1241
+ if (IS_ERR (dev ))
1242
+ return PTR_ERR (dev );
1243
+
1209
1244
if (r -> arp_flags & ATF_PUBL )
1210
1245
return arp_req_delete_public (net , r , dev );
1211
1246
1212
1247
ip = ((struct sockaddr_in * )& r -> arp_pa )-> sin_addr .s_addr ;
1213
- if (!dev ) {
1214
- dev = arp_req_dev (net , r );
1215
- if (IS_ERR (dev ))
1216
- return PTR_ERR (dev );
1217
- }
1248
+
1218
1249
return arp_invalidate (dev , ip , true);
1219
1250
}
1220
1251
@@ -1224,7 +1255,6 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
1224
1255
1225
1256
int arp_ioctl (struct net * net , unsigned int cmd , void __user * arg )
1226
1257
{
1227
- struct net_device * dev = NULL ;
1228
1258
struct arpreq r ;
1229
1259
__be32 * netmask ;
1230
1260
int err ;
@@ -1258,35 +1288,19 @@ int arp_ioctl(struct net *net, unsigned int cmd, void __user *arg)
1258
1288
return - EINVAL ;
1259
1289
1260
1290
rtnl_lock ();
1261
- if (r .arp_dev [0 ]) {
1262
- err = - ENODEV ;
1263
- dev = __dev_get_by_name (net , r .arp_dev );
1264
- if (!dev )
1265
- goto out ;
1266
-
1267
- /* Mmmm... It is wrong... ARPHRD_NETROM==0 */
1268
- if (!r .arp_ha .sa_family )
1269
- r .arp_ha .sa_family = dev -> type ;
1270
- err = - EINVAL ;
1271
- if ((r .arp_flags & ATF_COM ) && r .arp_ha .sa_family != dev -> type )
1272
- goto out ;
1273
- } else if (cmd == SIOCGARP ) {
1274
- err = - ENODEV ;
1275
- goto out ;
1276
- }
1277
1291
1278
1292
switch (cmd ) {
1279
1293
case SIOCDARP :
1280
- err = arp_req_delete (net , & r , dev );
1294
+ err = arp_req_delete (net , & r );
1281
1295
break ;
1282
1296
case SIOCSARP :
1283
- err = arp_req_set (net , & r , dev );
1297
+ err = arp_req_set (net , & r );
1284
1298
break ;
1285
1299
case SIOCGARP :
1286
- err = arp_req_get (& r , dev );
1300
+ err = arp_req_get (net , & r );
1287
1301
break ;
1288
1302
}
1289
- out :
1303
+
1290
1304
rtnl_unlock ();
1291
1305
if (cmd == SIOCGARP && !err && copy_to_user (arg , & r , sizeof (r )))
1292
1306
err = - EFAULT ;
0 commit comments