Wed Oct 14 11:22:55 2015 UTC ()
In the event of an error within arpresolve(), delete the cloned route
otherwise it would never be deleted.


(roy)
diff -r1.188 -r1.189 src/sys/netinet/if_arp.c

cvs diff -r1.188 -r1.189 src/sys/netinet/if_arp.c (expand / switch to unified diff)

--- src/sys/netinet/if_arp.c 2015/10/14 11:17:57 1.188
+++ src/sys/netinet/if_arp.c 2015/10/14 11:22:55 1.189
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: if_arp.c,v 1.188 2015/10/14 11:17:57 roy Exp $ */ 1/* $NetBSD: if_arp.c,v 1.189 2015/10/14 11:22:55 roy Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2000, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Public Access Networks Corporation ("Panix"). It was developed under 8 * by Public Access Networks Corporation ("Panix"). It was developed under
9 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon. 9 * contract to Panix by Eric Haszlakiewicz and Thor Lancelot Simon.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -58,27 +58,27 @@ @@ -58,27 +58,27 @@
58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 58 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
59 * SUCH DAMAGE. 59 * SUCH DAMAGE.
60 * 60 *
61 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94 61 * @(#)if_ether.c 8.2 (Berkeley) 9/26/94
62 */ 62 */
63 63
64/* 64/*
65 * Ethernet address resolution protocol. 65 * Ethernet address resolution protocol.
66 * TODO: 66 * TODO:
67 * add "inuse/lock" bit (or ref. count) along with valid bit 67 * add "inuse/lock" bit (or ref. count) along with valid bit
68 */ 68 */
69 69
70#include <sys/cdefs.h> 70#include <sys/cdefs.h>
71__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.188 2015/10/14 11:17:57 roy Exp $"); 71__KERNEL_RCSID(0, "$NetBSD: if_arp.c,v 1.189 2015/10/14 11:22:55 roy Exp $");
72 72
73#ifdef _KERNEL_OPT 73#ifdef _KERNEL_OPT
74#include "opt_ddb.h" 74#include "opt_ddb.h"
75#include "opt_inet.h" 75#include "opt_inet.h"
76#endif 76#endif
77 77
78#ifdef INET 78#ifdef INET
79 79
80#include "bridge.h" 80#include "bridge.h"
81 81
82#include <sys/param.h> 82#include <sys/param.h>
83#include <sys/systm.h> 83#include <sys/systm.h>
84#include <sys/callout.h> 84#include <sys/callout.h>
@@ -830,63 +830,62 @@ arpresolve(struct ifnet *ifp, struct rte @@ -830,63 +830,62 @@ arpresolve(struct ifnet *ifp, struct rte
830 rt->rt_expire = time_uptime; 830 rt->rt_expire = time_uptime;
831 } 831 }
832#endif 832#endif
833 833
834notfound: 834notfound:
835#ifdef IFF_STATICARP /* FreeBSD */ 835#ifdef IFF_STATICARP /* FreeBSD */
836#define _IFF_NOARP (IFF_NOARP | IFF_STATICARP) 836#define _IFF_NOARP (IFF_NOARP | IFF_STATICARP)
837#else 837#else
838#define _IFF_NOARP IFF_NOARP 838#define _IFF_NOARP IFF_NOARP
839#endif 839#endif
840 if (ifp->if_flags & _IFF_NOARP) { 840 if (ifp->if_flags & _IFF_NOARP) {
841 if (la != NULL) 841 if (la != NULL)
842 LLE_RUNLOCK(la); 842 LLE_RUNLOCK(la);
843 m_freem(m); 843 error = ENOTSUP;
844 return ENOTSUP; 844 goto bad;
845 } 845 }
846#undef _IFF_NOARP 846#undef _IFF_NOARP
847 if (la == NULL) { 847 if (la == NULL) {
848 create_lookup = "create"; 848 create_lookup = "create";
849 IF_AFDATA_WLOCK(ifp); 849 IF_AFDATA_WLOCK(ifp);
850 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst); 850 la = lla_create(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
851 IF_AFDATA_WUNLOCK(ifp); 851 IF_AFDATA_WUNLOCK(ifp);
852 if (la == NULL) 852 if (la == NULL)
853 ARP_STATINC(ARP_STAT_ALLOCFAIL); 853 ARP_STATINC(ARP_STAT_ALLOCFAIL);
854 } else if (LLE_TRY_UPGRADE(la) == 0) { 854 } else if (LLE_TRY_UPGRADE(la) == 0) {
855 create_lookup = "lookup"; 855 create_lookup = "lookup";
856 LLE_RUNLOCK(la); 856 LLE_RUNLOCK(la);
857 IF_AFDATA_RLOCK(ifp); 857 IF_AFDATA_RLOCK(ifp);
858 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst); 858 la = lla_lookup(LLTABLE(ifp), LLE_EXCLUSIVE, dst);
859 IF_AFDATA_RUNLOCK(ifp); 859 IF_AFDATA_RUNLOCK(ifp);
860 } 860 }
861 861
 862 error = EINVAL;
862 if (la == NULL) { 863 if (la == NULL) {
863 log(LOG_DEBUG, 864 log(LOG_DEBUG,
864 "%s: failed to %s llentry for %s on %s\n", 865 "%s: failed to %s llentry for %s on %s\n",
865 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr), 866 __func__, create_lookup, inet_ntoa(satocsin(dst)->sin_addr),
866 ifp->if_xname); 867 ifp->if_xname);
867 m_freem(m); 868 goto bad;
868 return EINVAL; 
869 } 869 }
870 870
871 /* Just in case */ 871 /* Just in case */
872 if (la->la_rt == NULL) { 872 if (la->la_rt == NULL) {
873 LLE_WUNLOCK(la); 873 LLE_WUNLOCK(la);
874 log(LOG_DEBUG, 874 log(LOG_DEBUG,
875 "%s: valid llentry has no rtentry for %s on %s\n", 875 "%s: valid llentry has no rtentry for %s on %s\n",
876 __func__, inet_ntoa(satocsin(dst)->sin_addr), 876 __func__, inet_ntoa(satocsin(dst)->sin_addr),
877 ifp->if_xname); 877 ifp->if_xname);
878 m_freem(m); 878 goto bad;
879 return EINVAL; 
880 } 879 }
881 rt = la->la_rt; 880 rt = la->la_rt;
882 881
883 if ((la->la_flags & LLE_VALID) && 882 if ((la->la_flags & LLE_VALID) &&
884 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime)) 883 ((la->la_flags & LLE_STATIC) || la->la_expire > time_uptime))
885 { 884 {
886 sdl = satocsdl(rt->rt_gateway); 885 sdl = satocsdl(rt->rt_gateway);
887 memcpy(desten, CLLADDR(sdl), 886 memcpy(desten, CLLADDR(sdl),
888 min(sdl->sdl_alen, ifp->if_addrlen)); 887 min(sdl->sdl_alen, ifp->if_addrlen));
889 renew = false; 888 renew = false;
890 /* 889 /*
891 * If entry has an expiry time and it is approaching, 890 * If entry has an expiry time and it is approaching,
892 * see if we need to send an ARP request within this 891 * see if we need to send an ARP request within this
@@ -907,31 +906,31 @@ notfound: @@ -907,31 +906,31 @@ notfound:
907 (rt->rt_ifp->if_type == IFT_CARP) ? 906 (rt->rt_ifp->if_type == IFT_CARP) ?
908 CLLADDR(rt->rt_ifp->if_sadl): 907 CLLADDR(rt->rt_ifp->if_sadl):
909#endif 908#endif
910 CLLADDR(ifp->if_sadl); 909 CLLADDR(ifp->if_sadl);
911 arprequest(ifp, 910 arprequest(ifp,
912 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 911 &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
913 &satocsin(dst)->sin_addr, enaddr); 912 &satocsin(dst)->sin_addr, enaddr);
914 } 913 }
915 914
916 return 0; 915 return 0;
917 } 916 }
918 917
919 if (la->la_flags & LLE_STATIC) { /* should not happen! */ 918 if (la->la_flags & LLE_STATIC) { /* should not happen! */
 919 LLE_RUNLOCK(la);
920 log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n", 920 log(LOG_DEBUG, "arpresolve: ouch, empty static llinfo for %s\n",
921 inet_ntoa(satocsin(dst)->sin_addr)); 921 inet_ntoa(satocsin(dst)->sin_addr));
922 m_freem(m); 
923 error = EINVAL; 922 error = EINVAL;
924 goto done; 923 goto bad;
925 } 924 }
926 925
927 renew = (la->la_asked == 0 || la->la_expire != time_uptime); 926 renew = (la->la_asked == 0 || la->la_expire != time_uptime);
928 927
929 /* 928 /*
930 * There is an arptab entry, but no ethernet address 929 * There is an arptab entry, but no ethernet address
931 * response yet. Add the mbuf to the list, dropping 930 * response yet. Add the mbuf to the list, dropping
932 * the oldest packet if we have exceeded the system 931 * the oldest packet if we have exceeded the system
933 * setting. 932 * setting.
934 */ 933 */
935 LLE_WLOCK_ASSERT(la); 934 LLE_WLOCK_ASSERT(la);
936 if (la->la_numheld >= arp_maxhold) { 935 if (la->la_numheld >= arp_maxhold) {
937 if (la->la_hold != NULL) { 936 if (la->la_hold != NULL) {
@@ -973,29 +972,36 @@ notfound: @@ -973,29 +972,36 @@ notfound:
973#endif 972#endif
974 CLLADDR(ifp->if_sadl); 973 CLLADDR(ifp->if_sadl);
975 LLE_ADDREF(la); 974 LLE_ADDREF(la);
976 la->la_expire = time_uptime; 975 la->la_expire = time_uptime;
977 callout_reset(&la->la_timer, hz * arpt_down, 976 callout_reset(&la->la_timer, hz * arpt_down,
978 arptimer, la); 977 arptimer, la);
979 la->la_asked++; 978 la->la_asked++;
980 LLE_WUNLOCK(la); 979 LLE_WUNLOCK(la);
981 980
982 arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr, 981 arprequest(ifp, &satocsin(rt->rt_ifa->ifa_addr)->sin_addr,
983 &satocsin(dst)->sin_addr, enaddr); 982 &satocsin(dst)->sin_addr, enaddr);
984 return error; 983 return error;
985 } 984 }
986done: 985
987 LLE_RUNLOCK(la); 986 LLE_RUNLOCK(la);
 987 return error;
988 988
 989bad:
 990 m_freem(m);
 991 if (rt != NULL && (rt->rt_flags & RTF_CLONED) != 0) {
 992 rtrequest(RTM_DELETE, rt_getkey(rt),
 993 rt->rt_gateway, rt_mask(rt), rt->rt_flags, NULL);
 994 }
989 return error; 995 return error;
990} 996}
991 997
992/* 998/*
993 * Common length and type checks are done here, 999 * Common length and type checks are done here,
994 * then the protocol-specific routine is called. 1000 * then the protocol-specific routine is called.
995 */ 1001 */
996void 1002void
997arpintr(void) 1003arpintr(void)
998{ 1004{
999 struct mbuf *m; 1005 struct mbuf *m;
1000 struct arphdr *ar; 1006 struct arphdr *ar;
1001 int s; 1007 int s;