| 1369 | } |
| 1370 | |
| 1371 | static int |
| 1372 | in_lltable_rtcheck(struct ifnet *ifp, u_int flags, const struct sockaddr *l3addr) |
| 1373 | { |
| 1374 | struct rt_addrinfo info; |
| 1375 | struct sockaddr_in rt_key, rt_mask; |
| 1376 | struct sockaddr rt_gateway; |
| 1377 | int rt_flags; |
| 1378 | |
| 1379 | KASSERT(l3addr->sa_family == AF_INET, |
| 1380 | ("sin_family %d", l3addr->sa_family)); |
| 1381 | |
| 1382 | bzero(&rt_key, sizeof(rt_key)); |
| 1383 | rt_key.sin_len = sizeof(rt_key); |
| 1384 | bzero(&rt_mask, sizeof(rt_mask)); |
| 1385 | rt_mask.sin_len = sizeof(rt_mask); |
| 1386 | bzero(&rt_gateway, sizeof(rt_gateway)); |
| 1387 | rt_gateway.sa_len = sizeof(rt_gateway); |
| 1388 | |
| 1389 | bzero(&info, sizeof(info)); |
| 1390 | info.rti_info[RTAX_DST] = (struct sockaddr *)&rt_key; |
| 1391 | info.rti_info[RTAX_NETMASK] = (struct sockaddr *)&rt_mask; |
| 1392 | info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway; |
| 1393 | |
| 1394 | if (rib_lookup_info(ifp->if_fib, l3addr, NHR_REF, 0, &info) != 0) |
| 1395 | return (EINVAL); |
| 1396 | |
| 1397 | rt_flags = info.rti_flags; |
| 1398 | |
| 1399 | /* |
| 1400 | * If the gateway for an existing host route matches the target L3 |
| 1401 | * address, which is a special route inserted by some implementation |
| 1402 | * such as MANET, and the interface is of the correct type, then |
| 1403 | * allow for ARP to proceed. |
| 1404 | */ |
| 1405 | if (rt_flags & RTF_GATEWAY) { |
| 1406 | if (!(rt_flags & RTF_HOST) || !info.rti_ifp || |
| 1407 | info.rti_ifp->if_type != IFT_ETHER || |
| 1408 | (info.rti_ifp->if_flags & (IFF_NOARP | IFF_STATICARP)) != 0 || |
| 1409 | memcmp(rt_gateway.sa_data, l3addr->sa_data, |
| 1410 | sizeof(in_addr_t)) != 0) { |
| 1411 | rib_free_info(&info); |
| 1412 | return (EINVAL); |
| 1413 | } |
| 1414 | } |
| 1415 | rib_free_info(&info); |
| 1416 | |
| 1417 | /* |
| 1418 | * Make sure that at least the destination address is covered |
| 1419 | * by the route. This is for handling the case where 2 or more |
| 1420 | * interfaces have the same prefix. An incoming packet arrives |
| 1421 | * on one interface and the corresponding outgoing packet leaves |
| 1422 | * another interface. |
| 1423 | */ |
| 1424 | if (!(rt_flags & RTF_HOST) && info.rti_ifp != ifp) { |
| 1425 | const char *sa, *mask, *addr, *lim; |
| 1426 | const struct sockaddr_in *l3sin; |
| 1427 | |
| 1428 | mask = (const char *)&rt_mask; |
no test coverage detected