diff --git a/net/arp/arp.h b/net/arp/arp.h index 1c4d44849c6..06a715b93db 100644 --- a/net/arp/arp.h +++ b/net/arp/arp.h @@ -164,6 +164,7 @@ struct arp_entry_s in_addr_t at_ipaddr; /* IP address */ struct ether_addr at_ethaddr; /* Hardware address */ clock_t at_time; /* Time of last usage */ + uint8_t at_flags; /* Flags, examples: ATF_PERM */ FAR struct net_driver_s *at_dev; /* The device driver structure */ }; @@ -471,6 +472,7 @@ void arp_cleanup(FAR struct net_driver_s *dev); * dev - The device driver structure * ipaddr - The IP address as an inaddr_t * ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN] + * flags - Flags, examples: ATF_PERM(Permanent entry) * * Returned Value: * Zero (OK) if the ARP table entry was successfully modified. A negated @@ -482,7 +484,7 @@ void arp_cleanup(FAR struct net_driver_s *dev); ****************************************************************************/ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, - FAR const uint8_t *ethaddr); + FAR const uint8_t *ethaddr, uint8_t flags); /**************************************************************************** * Name: arp_hdr_update @@ -623,7 +625,7 @@ void arp_acd_setup(FAR struct net_driver_s *dev); # define arp_find(i,e,d,u) (-ENOSYS) # define arp_delete(i,d) (-ENOSYS) # define arp_cleanup(d) -# define arp_update(d,i,m); +# define arp_update(d,i,m,f); # define arp_hdr_update(d,i,m); # define arp_snapshot(s,n) (0) # define arp_dump(arp) diff --git a/net/arp/arp_out.c b/net/arp/arp_out.c index fa465e30922..120b2deef10 100644 --- a/net/arp/arp_out.c +++ b/net/arp/arp_out.c @@ -283,7 +283,7 @@ void arp_out(FAR struct net_driver_s *dev) * send ARP request for same destination. */ - arp_update(dev, ipaddr, NULL); + arp_update(dev, ipaddr, NULL, 0); /* The destination address was not in our ARP table, so we overwrite * the IP packet with an ARP request. diff --git a/net/arp/arp_send.c b/net/arp/arp_send.c index 34c5f1acf14..a44bf3dd763 100644 --- a/net/arp/arp_send.c +++ b/net/arp/arp_send.c @@ -367,7 +367,7 @@ int arp_send(in_addr_t ipaddr) if (state.snd_retries == 0) { - arp_update(dev, ipaddr, NULL); + arp_update(dev, ipaddr, NULL, 0); sending = true; } diff --git a/net/arp/arp_table.c b/net/arp/arp_table.c index 3cdf35c4c0a..7c65b0f498f 100644 --- a/net/arp/arp_table.c +++ b/net/arp/arp_table.c @@ -169,6 +169,10 @@ arp_return_old_entry(FAR struct arp_entry_s *e1, FAR struct arp_entry_s *e2) { return e2; } + else if ((e1->at_flags & ATF_PERM) != (e2->at_flags & ATF_PERM)) + { + return (e1->at_flags & ATF_PERM) == 0 ? e1 : e2; + } else if ((int)(e1->at_time - e2->at_time) <= 0) { return e1; @@ -220,7 +224,8 @@ static FAR struct arp_entry_s *arp_lookup(in_addr_t ipaddr, /* Check if it has expired */ - if (clock_systime_ticks() - tabptr->at_time <= ARP_MAXAGE_TICK) + if ((tabptr->at_flags & ATF_PERM) != 0 || + clock_systime_ticks() - tabptr->at_time <= ARP_MAXAGE_TICK) { return tabptr; } @@ -279,6 +284,7 @@ static void arp_get_arpreq(FAR struct arpreq *output, * dev - The device driver structure * ipaddr - The IP address as an inaddr_t * ethaddr - Refers to a HW address uint8_t[IFHWADDRLEN] + * flags - Flags, examples: ATF_PERM(Permanent entry) * * Returned Value: * Zero (OK) if the ARP table entry was successfully modified. A negated @@ -290,7 +296,7 @@ static void arp_get_arpreq(FAR struct arpreq *output, ****************************************************************************/ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, - FAR const uint8_t *ethaddr) + FAR const uint8_t *ethaddr, uint8_t flags) { FAR struct arp_entry_s *tabptr = &g_arptable[0]; #ifdef CONFIG_NETLINK_ROUTE @@ -355,10 +361,14 @@ int arp_update(FAR struct net_driver_s *dev, in_addr_t ipaddr, * information. */ - tabptr->at_ipaddr = ipaddr; - memcpy(tabptr->at_ethaddr.ether_addr_octet, ethaddr, ETHER_ADDR_LEN); - tabptr->at_dev = dev; - tabptr->at_time = clock_systime_ticks(); + if ((tabptr->at_flags & ATF_PERM) == 0 || (flags & ATF_PERM) != 0) + { + memcpy(tabptr->at_ethaddr.ether_addr_octet, ethaddr, ETHER_ADDR_LEN); + tabptr->at_ipaddr = ipaddr; + tabptr->at_time = clock_systime_ticks(); + tabptr->at_flags = flags; + tabptr->at_dev = dev; + } /* Notify the new entry */ @@ -401,7 +411,7 @@ void arp_hdr_update(FAR struct net_driver_s *dev, FAR uint16_t *pipaddr, /* Update the ARP table */ - arp_update(dev, ipaddr, ethaddr); + arp_update(dev, ipaddr, ethaddr, 0); } /**************************************************************************** @@ -598,8 +608,8 @@ unsigned int arp_snapshot(FAR struct arpreq *snapshot, i++) { tabptr = &g_arptable[i]; - if (tabptr->at_ipaddr != 0 && - now - tabptr->at_time <= ARP_MAXAGE_TICK) + if (tabptr->at_ipaddr != 0 && ((tabptr->at_flags & ATF_PERM) != 0 || + now - tabptr->at_time <= ARP_MAXAGE_TICK)) { arp_get_arpreq(&snapshot[ncopied], tabptr); ncopied++; diff --git a/net/netdev/netdev_ioctl.c b/net/netdev/netdev_ioctl.c index 61efcac5f0f..70b05275f7d 100644 --- a/net/netdev/netdev_ioctl.c +++ b/net/netdev/netdev_ioctl.c @@ -1491,7 +1491,8 @@ static int netdev_arp_ioctl(FAR struct socket *psock, int cmd, */ ret = arp_update(dev, addr->sin_addr.s_addr, - (FAR const uint8_t *)req->arp_ha.sa_data); + (FAR const uint8_t *)req->arp_ha.sa_data, + req->arp_flags); } else {