Skip to content

Commit dd35734

Browse files
committed
Merge branch 'ipv4-invalidate-broadcast-neigh-upon-address-addition'
Ido Schimmel says: ==================== ipv4: Invalidate neighbour for broadcast address upon address addition Patch #1 solves a recently reported issue [1]. See detailed description in the changelog. Patch #2 adds a matching test case. Targeting at net-next since as far as I can tell this use case never worked. There are no regressions in fib_tests.sh with this change: # ./fib_tests.sh ... Tests passed: 186 Tests failed: 0 [1] https://lore.kernel.org/netdev/[email protected]/ ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 0f6938e + 25bd462 commit dd35734

File tree

4 files changed

+69
-4
lines changed

4 files changed

+69
-4
lines changed

include/net/arp.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ void arp_send(int type, int ptype, __be32 dest_ip,
6565
const unsigned char *src_hw, const unsigned char *th);
6666
int arp_mc_map(__be32 addr, u8 *haddr, struct net_device *dev, int dir);
6767
void arp_ifdown(struct net_device *dev);
68+
int arp_invalidate(struct net_device *dev, __be32 ip, bool force);
6869

6970
struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,
7071
struct net_device *dev, __be32 src_ip,

net/ipv4/arp.c

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1116,13 +1116,18 @@ static int arp_req_get(struct arpreq *r, struct net_device *dev)
11161116
return err;
11171117
}
11181118

1119-
static int arp_invalidate(struct net_device *dev, __be32 ip)
1119+
int arp_invalidate(struct net_device *dev, __be32 ip, bool force)
11201120
{
11211121
struct neighbour *neigh = neigh_lookup(&arp_tbl, &ip, dev);
11221122
int err = -ENXIO;
11231123
struct neigh_table *tbl = &arp_tbl;
11241124

11251125
if (neigh) {
1126+
if ((neigh->nud_state & NUD_VALID) && !force) {
1127+
neigh_release(neigh);
1128+
return 0;
1129+
}
1130+
11261131
if (neigh->nud_state & ~NUD_NOARP)
11271132
err = neigh_update(neigh, NULL, NUD_FAILED,
11281133
NEIGH_UPDATE_F_OVERRIDE|
@@ -1169,7 +1174,7 @@ static int arp_req_delete(struct net *net, struct arpreq *r,
11691174
if (!dev)
11701175
return -EINVAL;
11711176
}
1172-
return arp_invalidate(dev, ip);
1177+
return arp_invalidate(dev, ip, true);
11731178
}
11741179

11751180
/*

net/ipv4/fib_frontend.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1124,9 +1124,11 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
11241124
return;
11251125

11261126
/* Add broadcast address, if it is explicitly assigned. */
1127-
if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF))
1127+
if (ifa->ifa_broadcast && ifa->ifa_broadcast != htonl(0xFFFFFFFF)) {
11281128
fib_magic(RTM_NEWROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32,
11291129
prim, 0);
1130+
arp_invalidate(dev, ifa->ifa_broadcast, false);
1131+
}
11301132

11311133
if (!ipv4_is_zeronet(prefix) && !(ifa->ifa_flags & IFA_F_SECONDARY) &&
11321134
(prefix != addr || ifa->ifa_prefixlen < 32)) {
@@ -1140,6 +1142,7 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)
11401142
if (ifa->ifa_prefixlen < 31) {
11411143
fib_magic(RTM_NEWROUTE, RTN_BROADCAST, prefix | ~mask,
11421144
32, prim, 0);
1145+
arp_invalidate(dev, prefix | ~mask, false);
11431146
}
11441147
}
11451148
}

tools/testing/selftests/net/fib_tests.sh

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ ret=0
99
ksft_skip=4
1010

1111
# all tests in this script. Can be overridden with -t option
12-
TESTS="unregister down carrier nexthop suppress ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr ipv4_mangle ipv6_mangle"
12+
TESTS="unregister down carrier nexthop suppress ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr ipv4_mangle ipv6_mangle ipv4_bcast_neigh"
1313

1414
VERBOSE=0
1515
PAUSE_ON_FAIL=no
@@ -1954,6 +1954,61 @@ ipv6_mangle_test()
19541954
route_cleanup
19551955
}
19561956

1957+
ip_neigh_get_check()
1958+
{
1959+
ip neigh help 2>&1 | grep -q 'ip neigh get'
1960+
if [ $? -ne 0 ]; then
1961+
echo "iproute2 command does not support neigh get. Skipping test"
1962+
return 1
1963+
fi
1964+
1965+
return 0
1966+
}
1967+
1968+
ipv4_bcast_neigh_test()
1969+
{
1970+
local rc
1971+
1972+
echo
1973+
echo "IPv4 broadcast neighbour tests"
1974+
1975+
ip_neigh_get_check || return 1
1976+
1977+
setup
1978+
1979+
set -e
1980+
run_cmd "$IP neigh add 192.0.2.111 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
1981+
run_cmd "$IP neigh add 192.0.2.255 lladdr 00:11:22:33:44:55 nud perm dev dummy0"
1982+
1983+
run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
1984+
run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
1985+
1986+
run_cmd "$IP address add 192.0.2.1/24 broadcast 192.0.2.111 dev dummy0"
1987+
1988+
run_cmd "$IP neigh add 203.0.113.111 nud failed dev dummy0"
1989+
run_cmd "$IP neigh add 203.0.113.255 nud failed dev dummy0"
1990+
1991+
run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
1992+
run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
1993+
1994+
run_cmd "$IP address add 203.0.113.1/24 broadcast 203.0.113.111 dev dummy0"
1995+
set +e
1996+
1997+
run_cmd "$IP neigh get 192.0.2.111 dev dummy0"
1998+
log_test $? 0 "Resolved neighbour for broadcast address"
1999+
2000+
run_cmd "$IP neigh get 192.0.2.255 dev dummy0"
2001+
log_test $? 0 "Resolved neighbour for network broadcast address"
2002+
2003+
run_cmd "$IP neigh get 203.0.113.111 dev dummy0"
2004+
log_test $? 2 "Unresolved neighbour for broadcast address"
2005+
2006+
run_cmd "$IP neigh get 203.0.113.255 dev dummy0"
2007+
log_test $? 2 "Unresolved neighbour for network broadcast address"
2008+
2009+
cleanup
2010+
}
2011+
19572012
################################################################################
19582013
# usage
19592014

@@ -2028,6 +2083,7 @@ do
20282083
ipv4_route_v6_gw) ipv4_route_v6_gw_test;;
20292084
ipv4_mangle) ipv4_mangle_test;;
20302085
ipv6_mangle) ipv6_mangle_test;;
2086+
ipv4_bcast_neigh) ipv4_bcast_neigh_test;;
20312087

20322088
help) echo "Test names: $TESTS"; exit 0;;
20332089
esac

0 commit comments

Comments
 (0)