arp: Implement sticky ARP mode for interfaces.
Provide sticky ARP flag for network interface which marks it as the "sticky" one similarly to what we have for bridges. Once interface is marked sticky, any address resolved using the ARP will be saved as a static one in the ARP table. Such functionality may be used to prevent ARP spoofing or to decrease latencies in Ethernet networks. The drawbacks include potential limitations in usage of ARP-based load-balancers and high-availability solutions such as carp(4). The implemented option is disabled by default, therefore should not impact the default behaviour of the networking stack. Sponsored by: Conclusive Engineering sp. z o.o. Reviewed By: melifaro, pauamma_gundo.com Differential Revision: https://reviews.freebsd.org/D35314 MFC after: 2 weeks
This commit is contained in:
parent
18054d0220
commit
c9a5c48ae8
@ -28,7 +28,7 @@
|
||||
.\" From: @(#)ifconfig.8 8.3 (Berkeley) 1/5/94
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd April 11, 2022
|
||||
.Dd May 26, 2022
|
||||
.Dt IFCONFIG 8
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -419,6 +419,23 @@ and will never send any requests.
|
||||
If the Address Resolution Protocol is enabled,
|
||||
the host will perform normally,
|
||||
sending out requests and listening for replies.
|
||||
.It Cm stickyarp
|
||||
Enable so-called sticky ARP mode for the interface.
|
||||
If this option is enabled on the given interface, any resolved address is
|
||||
marked as a static one and never expires. This may be used to increase
|
||||
security of the network by preventing ARP spoofing or to reduce latency for
|
||||
high-performance Ethernet networks where the time needed for ARP resolution is
|
||||
too high. Please note that a similar feature is also provided for bridges. See
|
||||
the sticky option in the
|
||||
.Sx Bridge Interface Parameters
|
||||
section. Enabling this
|
||||
option may impact techniques which rely on ARP expiration/overwriting feature
|
||||
such as load-balancers or high-availabity solutions such as
|
||||
.Xr carp 4 .
|
||||
.It Fl stickyarp
|
||||
Disable so-called sticky ARP mode for the interface (default).
|
||||
Resolved addresses will expire normally respecting the kernel ARP
|
||||
configuration.
|
||||
.It Cm broadcast
|
||||
(Inet only.)
|
||||
Specify the address to use to represent broadcasts to the
|
||||
|
@ -1407,7 +1407,7 @@ unsetifdescr(const char *val, int value, int s, const struct afswtch *afp)
|
||||
#define IFFBITS \
|
||||
"\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\7RUNNING" \
|
||||
"\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \
|
||||
"\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP"
|
||||
"\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP\25STICKYARP"
|
||||
|
||||
#define IFCAPBITS \
|
||||
"\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \
|
||||
@ -1771,6 +1771,8 @@ static struct cmd basic_cmds[] = {
|
||||
DEF_CMD("-mextpg", -IFCAP_MEXTPG, setifcap),
|
||||
DEF_CMD("staticarp", IFF_STATICARP, setifflags),
|
||||
DEF_CMD("-staticarp", -IFF_STATICARP, setifflags),
|
||||
DEF_CMD("stickyarp", IFF_STICKYARP, setifflags),
|
||||
DEF_CMD("-stickyarp", -IFF_STICKYARP, setifflags),
|
||||
DEF_CMD("rxcsum6", IFCAP_RXCSUM_IPV6, setifcap),
|
||||
DEF_CMD("-rxcsum6", -IFCAP_RXCSUM_IPV6, setifcap),
|
||||
DEF_CMD("txcsum6", IFCAP_TXCSUM_IPV6, setifcap),
|
||||
|
@ -160,6 +160,7 @@ struct if_data {
|
||||
#define IFF_PPROMISC 0x20000 /* (n) user-requested promisc mode */
|
||||
#define IFF_MONITOR 0x40000 /* (n) user-requested monitor mode */
|
||||
#define IFF_STATICARP 0x80000 /* (n) static ARP */
|
||||
#define IFF_STICKYARP 0x100000 /* (n) sticky ARP */
|
||||
#define IFF_DYING 0x200000 /* (n) interface is winding down */
|
||||
#define IFF_RENAMING 0x400000 /* (n) interface is being renamed */
|
||||
#define IFF_NOGROUP 0x800000 /* (n) interface is not part of any groups */
|
||||
|
@ -186,7 +186,7 @@ static void in_arpinput(struct mbuf *);
|
||||
|
||||
static void arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr,
|
||||
struct ifnet *ifp, int bridged, struct llentry *la);
|
||||
static void arp_mark_lle_reachable(struct llentry *la);
|
||||
static void arp_mark_lle_reachable(struct llentry *la, struct ifnet *ifp);
|
||||
static void arp_iflladdr(void *arg __unused, struct ifnet *ifp);
|
||||
|
||||
static eventhandler_tag iflladdr_tag;
|
||||
@ -999,7 +999,7 @@ in_arpinput(struct mbuf *m)
|
||||
IF_AFDATA_WUNLOCK(ifp);
|
||||
|
||||
if (la_tmp == NULL) {
|
||||
arp_mark_lle_reachable(la);
|
||||
arp_mark_lle_reachable(la, ifp);
|
||||
LLE_WUNLOCK(la);
|
||||
} else {
|
||||
/* Free newly-create entry and handle packet */
|
||||
@ -1247,7 +1247,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
|
||||
llentry_mark_used(la);
|
||||
}
|
||||
|
||||
arp_mark_lle_reachable(la);
|
||||
arp_mark_lle_reachable(la, ifp);
|
||||
|
||||
/*
|
||||
* The packets are all freed within the call to the output
|
||||
@ -1267,7 +1267,7 @@ arp_check_update_lle(struct arphdr *ah, struct in_addr isaddr, struct ifnet *ifp
|
||||
}
|
||||
|
||||
static void
|
||||
arp_mark_lle_reachable(struct llentry *la)
|
||||
arp_mark_lle_reachable(struct llentry *la, struct ifnet *ifp)
|
||||
{
|
||||
int canceled, wtime;
|
||||
|
||||
@ -1276,6 +1276,9 @@ arp_mark_lle_reachable(struct llentry *la)
|
||||
la->ln_state = ARP_LLINFO_REACHABLE;
|
||||
EVENTHANDLER_INVOKE(lle_event, la, LLENTRY_RESOLVED);
|
||||
|
||||
if ((ifp->if_flags & IFF_STICKYARP) != 0)
|
||||
la->la_flags |= LLE_STATIC;
|
||||
|
||||
if (!(la->la_flags & LLE_STATIC)) {
|
||||
LLE_ADDREF(la);
|
||||
la->la_expire = time_uptime + V_arpt_keep;
|
||||
|
Loading…
Reference in New Issue
Block a user