diff -urNp src/sbin/ifconfig/ifconfig.c src-proxyarp/sbin/ifconfig/ifconfig.c --- src/sbin/ifconfig/ifconfig.c 2010-12-21 21:09:25.000000000 +0400 +++ src-proxyarp/sbin/ifconfig/ifconfig.c 2012-03-11 15:08:20.000000000 +0400 @@ -860,7 +860,7 @@ unsetifdescr(const char *val, int value, #define IFFBITS \ "\020\1UP\2BROADCAST\3DEBUG\4LOOPBACK\5POINTOPOINT\6SMART\7RUNNING" \ "\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX\15LINK0\16LINK1\17LINK2" \ -"\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP" +"\20MULTICAST\22PPROMISC\23MONITOR\24STATICARP\30PROXYARP" #define IFCAPBITS \ "\020\1RXCSUM\2TXCSUM\3NETCONS\4VLAN_MTU\5VLAN_HWTAGGING\6JUMBO_MTU\7POLLING" \ @@ -1150,6 +1150,8 @@ static struct cmd basic_cmds[] = { DEF_CMD("noicmp", IFF_LINK1, setifflags), DEF_CMD_ARG("mtu", setifmtu), DEF_CMD_ARG("name", setifname), + DEF_CMD("proxyarp", IFF_PROXYARP, setifflags), + DEF_CMD("-proxyarp", -IFF_PROXYARP, setifflags), }; static __constructor void diff -urNp src/sys/net/if.h src-proxyarp/sys/net/if.h --- src/sys/net/if.h 2010-12-21 21:09:25.000000000 +0400 +++ src-proxyarp/sys/net/if.h 2012-03-11 15:09:57.000000000 +0400 @@ -151,6 +151,7 @@ struct if_data { #define IFF_STATICARP 0x80000 /* (n) static ARP */ #define IFF_DYING 0x200000 /* (n) interface is winding down */ #define IFF_RENAMING 0x400000 /* (n) interface is being renamed */ +#define IFF_PROXYARP 0x800000 /* (n) enable "local-proxy-arp" mode */ /* * Old names for driver flags so that user space tools can continue to use diff -urNp src/sys/netinet/if_ether.c src-proxyarp/sys/netinet/if_ether.c --- src/sys/netinet/if_ether.c 2010-12-21 21:09:25.000000000 +0400 +++ src-proxyarp/sys/netinet/if_ether.c 2012-03-11 15:18:31.000000000 +0400 @@ -731,7 +731,7 @@ reply: if (lle != NULL) LLE_RUNLOCK(lle); - if (!V_arp_proxyall) + if (!V_arp_proxyall && !(ifp->if_flags & IFF_PROXYARP)) goto drop; sin.sin_addr = itaddr; @@ -745,10 +745,22 @@ reply: * as this one came out of, or we'll get into a fight * over who claims what Ether address. */ - if (!rt->rt_ifp || rt->rt_ifp == ifp) { + if (!rt->rt_ifp || \ + (rt->rt_ifp == ifp && !(ifp->if_flags & IFF_PROXYARP))) { + RTFREE_LOCKED(rt); + goto drop; + } + + /* + * PROXYARP: Windows workaround + */ + + if ((ifp->if_flags & IFF_PROXYARP) && \ + (isaddr.s_addr == itaddr.s_addr)) { RTFREE_LOCKED(rt); goto drop; } + RTFREE_LOCKED(rt); (void)memcpy(ar_tha(ah), ar_sha(ah), ah->ar_hln);