| @@ -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 | |
834 | notfound: | | 834 | notfound: |
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 | } |
986 | done: | | 985 | |
987 | LLE_RUNLOCK(la); | | 986 | LLE_RUNLOCK(la); |
| | | 987 | return error; |
988 | | | 988 | |
| | | 989 | bad: |
| | | 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 | */ |
996 | void | | 1002 | void |
997 | arpintr(void) | | 1003 | arpintr(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; |