Skip to content

Commit 739278e

Browse files
mshawcroftTomasz Bursztyka
authored andcommitted
ethernet/arp: Use gateway for non local ipv4 routing.
Detect non local IPv4 destination addresses earlier and route them via the gw address. Ensure that the ARP table is populated with the GW address rather than the final destination address. Jira: ZEP-1473 Change-Id: I3b628584148b760340ef0fea4da4e8893702c832 Signed-off-by: Marcus Shawcroft <[email protected]>
1 parent 2fc5eb2 commit 739278e

File tree

1 file changed

+17
-11
lines changed

1 file changed

+17
-11
lines changed

subsys/net/ip/l2/arp.c

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,7 @@ static inline struct in_addr *if_get_addr(struct net_if *iface)
108108
}
109109

110110
static inline struct net_buf *prepare_arp(struct net_if *iface,
111+
struct in_addr *next_addr,
111112
struct arp_entry *entry,
112113
struct net_buf *pending)
113114
{
@@ -143,7 +144,7 @@ static inline struct net_buf *prepare_arp(struct net_if *iface,
143144
entry->pending = net_buf_ref(pending);
144145
entry->iface = net_nbuf_iface(buf);
145146

146-
net_ipaddr_copy(&entry->ip, &NET_IPV4_BUF(pending)->dst);
147+
net_ipaddr_copy(&entry->ip, next_addr);
147148

148149
memcpy(&eth->src.addr,
149150
net_if_get_link_addr(entry->iface)->addr,
@@ -165,12 +166,7 @@ static inline struct net_buf *prepare_arp(struct net_if *iface,
165166

166167
memset(&hdr->dst_hwaddr.addr, 0x00, sizeof(struct net_eth_addr));
167168

168-
/* Is the destination in local network */
169-
if (!net_if_ipv4_addr_mask_cmp(iface, &NET_IPV4_BUF(pending)->dst)) {
170-
net_ipaddr_copy(&hdr->dst_ipaddr, &iface->ipv4.gw);
171-
} else {
172-
net_ipaddr_copy(&hdr->dst_ipaddr, &NET_IPV4_BUF(pending)->dst);
173-
}
169+
net_ipaddr_copy(&hdr->dst_ipaddr, next_addr);
174170

175171
memcpy(hdr->src_hwaddr.addr, eth->src.addr,
176172
sizeof(struct net_eth_addr));
@@ -203,6 +199,7 @@ struct net_buf *net_arp_prepare(struct net_buf *buf)
203199
struct arp_entry *entry, *free_entry = NULL, *non_pending = NULL;
204200
struct net_linkaddr *ll;
205201
struct net_eth_hdr *hdr;
202+
struct in_addr *addr;
206203

207204
if (!buf || !buf->frags) {
208205
return NULL;
@@ -239,12 +236,21 @@ struct net_buf *net_arp_prepare(struct net_buf *buf)
239236

240237
hdr = (struct net_eth_hdr *)net_nbuf_ll(buf);
241238

239+
/* Is the destination in the local network, if not route via
240+
* the gateway address.
241+
*/
242+
if (!net_if_ipv4_addr_mask_cmp(net_nbuf_iface(buf),
243+
&NET_IPV4_BUF(buf)->dst)) {
244+
addr = &net_nbuf_iface(buf)->ipv4.gw;
245+
} else {
246+
addr = &NET_IPV4_BUF(buf)->dst;
247+
}
248+
242249
/* If the destination address is already known, we do not need
243250
* to send any ARP packet.
244251
*/
245252
entry = find_entry(net_nbuf_iface(buf),
246-
&NET_IPV4_BUF(buf)->dst,
247-
&free_entry, &non_pending);
253+
addr, &free_entry, &non_pending);
248254
if (!entry) {
249255
if (!free_entry) {
250256
/* So all the slots are occupied, use the first
@@ -259,7 +265,7 @@ struct net_buf *net_arp_prepare(struct net_buf *buf)
259265
struct net_buf *req;
260266

261267
req = prepare_arp(net_nbuf_iface(buf),
262-
NULL, buf);
268+
addr, NULL, buf);
263269
NET_DBG("Resending ARP %p", req);
264270

265271
net_nbuf_unref(buf);
@@ -270,7 +276,7 @@ struct net_buf *net_arp_prepare(struct net_buf *buf)
270276
free_entry = non_pending;
271277
}
272278

273-
return prepare_arp(net_nbuf_iface(buf), free_entry, buf);
279+
return prepare_arp(net_nbuf_iface(buf), addr, free_entry, buf);
274280
}
275281

276282
ll = net_if_get_link_addr(entry->iface);

0 commit comments

Comments
 (0)