| @@ -1,14 +1,14 @@ | | | @@ -1,14 +1,14 @@ |
1 | /* $NetBSD: ip_carp.c,v 1.107 2020/01/20 18:38:22 thorpej Exp $ */ | | 1 | /* $NetBSD: ip_carp.c,v 1.108 2020/01/29 04:37:24 thorpej Exp $ */ |
2 | /* $OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $ */ | | 2 | /* $OpenBSD: ip_carp.c,v 1.113 2005/11/04 08:11:54 mcbride Exp $ */ |
3 | | | 3 | |
4 | /* | | 4 | /* |
5 | * Copyright (c) 2002 Michael Shalayeff. All rights reserved. | | 5 | * Copyright (c) 2002 Michael Shalayeff. All rights reserved. |
6 | * Copyright (c) 2003 Ryan McBride. All rights reserved. | | 6 | * Copyright (c) 2003 Ryan McBride. All rights reserved. |
7 | * | | 7 | * |
8 | * Redistribution and use in source and binary forms, with or without | | 8 | * Redistribution and use in source and binary forms, with or without |
9 | * modification, are permitted provided that the following conditions | | 9 | * modification, are permitted provided that the following conditions |
10 | * are met: | | 10 | * are met: |
11 | * 1. Redistributions of source code must retain the above copyright | | 11 | * 1. Redistributions of source code must retain the above copyright |
12 | * notice, this list of conditions and the following disclaimer. | | 12 | * notice, this list of conditions and the following disclaimer. |
13 | * 2. Redistributions in binary form must reproduce the above copyright | | 13 | * 2. Redistributions in binary form must reproduce the above copyright |
14 | * notice, this list of conditions and the following disclaimer in the | | 14 | * notice, this list of conditions and the following disclaimer in the |
| @@ -23,27 +23,27 @@ | | | @@ -23,27 +23,27 @@ |
23 | * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | | 23 | * SERVICES; LOSS OF MIND, USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, | | 24 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, |
25 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING | | 25 | * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING |
26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF | | 26 | * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF |
27 | * THE POSSIBILITY OF SUCH DAMAGE. | | 27 | * THE POSSIBILITY OF SUCH DAMAGE. |
28 | */ | | 28 | */ |
29 | | | 29 | |
30 | #ifdef _KERNEL_OPT | | 30 | #ifdef _KERNEL_OPT |
31 | #include "opt_inet.h" | | 31 | #include "opt_inet.h" |
32 | #include "opt_mbuftrace.h" | | 32 | #include "opt_mbuftrace.h" |
33 | #endif | | 33 | #endif |
34 | | | 34 | |
35 | #include <sys/cdefs.h> | | 35 | #include <sys/cdefs.h> |
36 | __KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.107 2020/01/20 18:38:22 thorpej Exp $"); | | 36 | __KERNEL_RCSID(0, "$NetBSD: ip_carp.c,v 1.108 2020/01/29 04:37:24 thorpej Exp $"); |
37 | | | 37 | |
38 | /* | | 38 | /* |
39 | * TODO: | | 39 | * TODO: |
40 | * - iface reconfigure | | 40 | * - iface reconfigure |
41 | * - support for hardware checksum calculations; | | 41 | * - support for hardware checksum calculations; |
42 | * | | 42 | * |
43 | */ | | 43 | */ |
44 | | | 44 | |
45 | #include <sys/param.h> | | 45 | #include <sys/param.h> |
46 | #include <sys/proc.h> | | 46 | #include <sys/proc.h> |
47 | #include <sys/mbuf.h> | | 47 | #include <sys/mbuf.h> |
48 | #include <sys/socket.h> | | 48 | #include <sys/socket.h> |
49 | #include <sys/socketvar.h> | | 49 | #include <sys/socketvar.h> |
| @@ -702,50 +702,49 @@ carp_proto_input_c(struct mbuf *m, struc | | | @@ -702,50 +702,49 @@ carp_proto_input_c(struct mbuf *m, struc |
702 | if (IN6_IS_ADDR_LINKLOCAL(&in6_found)) | | 702 | if (IN6_IS_ADDR_LINKLOCAL(&in6_found)) |
703 | in6_found.s6_addr16[1] = 0; | | 703 | in6_found.s6_addr16[1] = 0; |
704 | if (IN6_ARE_ADDR_EQUAL(&in6_src, &in6_found)) { | | 704 | if (IN6_ARE_ADDR_EQUAL(&in6_src, &in6_found)) { |
705 | pserialize_read_exit(s); | | 705 | pserialize_read_exit(s); |
706 | m_freem(m); | | 706 | m_freem(m); |
707 | return; | | 707 | return; |
708 | } | | 708 | } |
709 | } | | 709 | } |
710 | #endif /* INET6 */ | | 710 | #endif /* INET6 */ |
711 | pserialize_read_exit(s); | | 711 | pserialize_read_exit(s); |
712 | } | | 712 | } |
713 | | | 713 | |
714 | nanotime(&sc->sc_if.if_lastchange); | | 714 | nanotime(&sc->sc_if.if_lastchange); |
715 | sc->sc_if.if_ipackets++; | | 715 | if_statadd2(&sc->sc_if, if_ipackets, 1, if_ibytes, m->m_pkthdr.len); |
716 | sc->sc_if.if_ibytes += m->m_pkthdr.len; | | | |
717 | | | 716 | |
718 | /* verify the CARP version. */ | | 717 | /* verify the CARP version. */ |
719 | if (ch->carp_version != CARP_VERSION) { | | 718 | if (ch->carp_version != CARP_VERSION) { |
720 | CARP_STATINC(CARP_STAT_BADVER); | | 719 | CARP_STATINC(CARP_STAT_BADVER); |
721 | sc->sc_if.if_ierrors++; | | 720 | if_statinc(&sc->sc_if, if_ierrors); |
722 | CARP_LOG(sc, ("invalid version %d != %d", | | 721 | CARP_LOG(sc, ("invalid version %d != %d", |
723 | ch->carp_version, CARP_VERSION)); | | 722 | ch->carp_version, CARP_VERSION)); |
724 | m_freem(m); | | 723 | m_freem(m); |
725 | return; | | 724 | return; |
726 | } | | 725 | } |
727 | | | 726 | |
728 | /* verify the hash */ | | 727 | /* verify the hash */ |
729 | if (carp_hmac_verify(sc, ch->carp_counter, ch->carp_md)) { | | 728 | if (carp_hmac_verify(sc, ch->carp_counter, ch->carp_md)) { |
730 | struct ip *ip; | | 729 | struct ip *ip; |
731 | char ipbuf[INET_ADDRSTRLEN]; | | 730 | char ipbuf[INET_ADDRSTRLEN]; |
732 | #ifdef INET6 | | 731 | #ifdef INET6 |
733 | struct ip6_hdr *ip6; | | 732 | struct ip6_hdr *ip6; |
734 | char ip6buf[INET6_ADDRSTRLEN]; | | 733 | char ip6buf[INET6_ADDRSTRLEN]; |
735 | #endif | | 734 | #endif |
736 | | | 735 | |
737 | CARP_STATINC(CARP_STAT_BADAUTH); | | 736 | CARP_STATINC(CARP_STAT_BADAUTH); |
738 | sc->sc_if.if_ierrors++; | | 737 | if_statinc(&sc->sc_if, if_ierrors); |
739 | | | 738 | |
740 | switch(af) { | | 739 | switch(af) { |
741 | case AF_INET: | | 740 | case AF_INET: |
742 | ip = mtod(m, struct ip *); | | 741 | ip = mtod(m, struct ip *); |
743 | CARP_LOG(sc, ("incorrect hash from %s", | | 742 | CARP_LOG(sc, ("incorrect hash from %s", |
744 | IN_PRINT(ipbuf, &ip->ip_src))); | | 743 | IN_PRINT(ipbuf, &ip->ip_src))); |
745 | break; | | 744 | break; |
746 | | | 745 | |
747 | #ifdef INET6 | | 746 | #ifdef INET6 |
748 | case AF_INET6: | | 747 | case AF_INET6: |
749 | ip6 = mtod(m, struct ip6_hdr *); | | 748 | ip6 = mtod(m, struct ip6_hdr *); |
750 | CARP_LOG(sc, ("incorrect hash from %s", | | 749 | CARP_LOG(sc, ("incorrect hash from %s", |
751 | IN6_PRINT(ip6buf, &ip6->ip6_src))); | | 750 | IN6_PRINT(ip6buf, &ip6->ip6_src))); |
| @@ -1028,27 +1027,27 @@ carp_send_ad(void *v) | | | @@ -1028,27 +1027,27 @@ carp_send_ad(void *v) |
1028 | struct carp_header ch; | | 1027 | struct carp_header ch; |
1029 | struct timeval tv; | | 1028 | struct timeval tv; |
1030 | struct carp_softc *sc = v; | | 1029 | struct carp_softc *sc = v; |
1031 | struct carp_header *ch_ptr; | | 1030 | struct carp_header *ch_ptr; |
1032 | struct mbuf *m; | | 1031 | struct mbuf *m; |
1033 | int error, len, advbase, advskew, s; | | 1032 | int error, len, advbase, advskew, s; |
1034 | struct sockaddr sa; | | 1033 | struct sockaddr sa; |
1035 | | | 1034 | |
1036 | KERNEL_LOCK(1, NULL); | | 1035 | KERNEL_LOCK(1, NULL); |
1037 | s = splsoftnet(); | | 1036 | s = splsoftnet(); |
1038 | | | 1037 | |
1039 | advbase = advskew = 0; /* Sssssh compiler */ | | 1038 | advbase = advskew = 0; /* Sssssh compiler */ |
1040 | if (sc->sc_carpdev == NULL) { | | 1039 | if (sc->sc_carpdev == NULL) { |
1041 | sc->sc_if.if_oerrors++; | | 1040 | if_statinc(&sc->sc_if, if_oerrors); |
1042 | goto retry_later; | | 1041 | goto retry_later; |
1043 | } | | 1042 | } |
1044 | | | 1043 | |
1045 | /* bow out if we've gone to backup (the carp interface is going down) */ | | 1044 | /* bow out if we've gone to backup (the carp interface is going down) */ |
1046 | if (sc->sc_bow_out) { | | 1045 | if (sc->sc_bow_out) { |
1047 | sc->sc_bow_out = 0; | | 1046 | sc->sc_bow_out = 0; |
1048 | advbase = 255; | | 1047 | advbase = 255; |
1049 | advskew = 255; | | 1048 | advskew = 255; |
1050 | } else { | | 1049 | } else { |
1051 | advbase = sc->sc_advbase; | | 1050 | advbase = sc->sc_advbase; |
1052 | if (!carp_suppress_preempt || sc->sc_advskew > 240) | | 1051 | if (!carp_suppress_preempt || sc->sc_advskew > 240) |
1053 | advskew = sc->sc_advskew; | | 1052 | advskew = sc->sc_advskew; |
1054 | else | | 1053 | else |
| @@ -1065,27 +1064,27 @@ carp_send_ad(void *v) | | | @@ -1065,27 +1064,27 @@ carp_send_ad(void *v) |
1065 | ch.carp_authlen = 7; /* XXX DEFINE */ | | 1064 | ch.carp_authlen = 7; /* XXX DEFINE */ |
1066 | ch.carp_pad1 = 0; /* must be zero */ | | 1065 | ch.carp_pad1 = 0; /* must be zero */ |
1067 | ch.carp_cksum = 0; | | 1066 | ch.carp_cksum = 0; |
1068 | | | 1067 | |
1069 | | | 1068 | |
1070 | #ifdef INET | | 1069 | #ifdef INET |
1071 | if (sc->sc_naddrs) { | | 1070 | if (sc->sc_naddrs) { |
1072 | struct ip *ip; | | 1071 | struct ip *ip; |
1073 | struct ifaddr *ifa; | | 1072 | struct ifaddr *ifa; |
1074 | int _s; | | 1073 | int _s; |
1075 | | | 1074 | |
1076 | MGETHDR(m, M_DONTWAIT, MT_HEADER); | | 1075 | MGETHDR(m, M_DONTWAIT, MT_HEADER); |
1077 | if (m == NULL) { | | 1076 | if (m == NULL) { |
1078 | sc->sc_if.if_oerrors++; | | 1077 | if_statinc(&sc->sc_if, if_oerrors); |
1079 | CARP_STATINC(CARP_STAT_ONOMEM); | | 1078 | CARP_STATINC(CARP_STAT_ONOMEM); |
1080 | /* XXX maybe less ? */ | | 1079 | /* XXX maybe less ? */ |
1081 | goto retry_later; | | 1080 | goto retry_later; |
1082 | } | | 1081 | } |
1083 | MCLAIM(m, &carp_proto_mowner_tx); | | 1082 | MCLAIM(m, &carp_proto_mowner_tx); |
1084 | len = sizeof(*ip) + sizeof(ch); | | 1083 | len = sizeof(*ip) + sizeof(ch); |
1085 | m->m_pkthdr.len = len; | | 1084 | m->m_pkthdr.len = len; |
1086 | m_reset_rcvif(m); | | 1085 | m_reset_rcvif(m); |
1087 | m->m_len = len; | | 1086 | m->m_len = len; |
1088 | m_align(m, m->m_len); | | 1087 | m_align(m, m->m_len); |
1089 | m->m_flags |= M_MCAST; | | 1088 | m->m_flags |= M_MCAST; |
1090 | ip = mtod(m, struct ip *); | | 1089 | ip = mtod(m, struct ip *); |
1091 | ip->ip_v = IPVERSION; | | 1090 | ip->ip_v = IPVERSION; |
| @@ -1109,38 +1108,37 @@ carp_send_ad(void *v) | | | @@ -1109,38 +1108,37 @@ carp_send_ad(void *v) |
1109 | ifatoia(ifa)->ia_addr.sin_addr.s_addr; | | 1108 | ifatoia(ifa)->ia_addr.sin_addr.s_addr; |
1110 | pserialize_read_exit(_s); | | 1109 | pserialize_read_exit(_s); |
1111 | ip->ip_dst.s_addr = INADDR_CARP_GROUP; | | 1110 | ip->ip_dst.s_addr = INADDR_CARP_GROUP; |
1112 | | | 1111 | |
1113 | ch_ptr = (struct carp_header *)(&ip[1]); | | 1112 | ch_ptr = (struct carp_header *)(&ip[1]); |
1114 | memcpy(ch_ptr, &ch, sizeof(ch)); | | 1113 | memcpy(ch_ptr, &ch, sizeof(ch)); |
1115 | carp_prepare_ad(m, sc, ch_ptr); | | 1114 | carp_prepare_ad(m, sc, ch_ptr); |
1116 | | | 1115 | |
1117 | m->m_data += sizeof(*ip); | | 1116 | m->m_data += sizeof(*ip); |
1118 | ch_ptr->carp_cksum = carp_cksum(m, len - sizeof(*ip)); | | 1117 | ch_ptr->carp_cksum = carp_cksum(m, len - sizeof(*ip)); |
1119 | m->m_data -= sizeof(*ip); | | 1118 | m->m_data -= sizeof(*ip); |
1120 | | | 1119 | |
1121 | nanotime(&sc->sc_if.if_lastchange); | | 1120 | nanotime(&sc->sc_if.if_lastchange); |
1122 | sc->sc_if.if_opackets++; | | 1121 | if_statadd2(&sc->sc_if, if_opackets, 1, if_obytes, len); |
1123 | sc->sc_if.if_obytes += len; | | | |
1124 | CARP_STATINC(CARP_STAT_OPACKETS); | | 1122 | CARP_STATINC(CARP_STAT_OPACKETS); |
1125 | | | 1123 | |
1126 | error = ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, | | 1124 | error = ip_output(m, NULL, NULL, IP_RAWOUTPUT, &sc->sc_imo, |
1127 | NULL); | | 1125 | NULL); |
1128 | if (error) { | | 1126 | if (error) { |
1129 | if (error == ENOBUFS) | | 1127 | if (error == ENOBUFS) |
1130 | CARP_STATINC(CARP_STAT_ONOMEM); | | 1128 | CARP_STATINC(CARP_STAT_ONOMEM); |
1131 | else | | 1129 | else |
1132 | CARP_LOG(sc, ("ip_output failed: %d", error)); | | 1130 | CARP_LOG(sc, ("ip_output failed: %d", error)); |
1133 | sc->sc_if.if_oerrors++; | | 1131 | if_statinc(&sc->sc_if, if_oerrors); |
1134 | if (sc->sc_sendad_errors < INT_MAX) | | 1132 | if (sc->sc_sendad_errors < INT_MAX) |
1135 | sc->sc_sendad_errors++; | | 1133 | sc->sc_sendad_errors++; |
1136 | if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) { | | 1134 | if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) { |
1137 | carp_suppress_preempt++; | | 1135 | carp_suppress_preempt++; |
1138 | if (carp_suppress_preempt == 1) | | 1136 | if (carp_suppress_preempt == 1) |
1139 | carp_send_ad_all(); | | 1137 | carp_send_ad_all(); |
1140 | } | | 1138 | } |
1141 | sc->sc_sendad_success = 0; | | 1139 | sc->sc_sendad_success = 0; |
1142 | } else { | | 1140 | } else { |
1143 | if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) { | | 1141 | if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) { |
1144 | if (++sc->sc_sendad_success >= | | 1142 | if (++sc->sc_sendad_success >= |
1145 | CARP_SENDAD_MIN_SUCCESS) { | | 1143 | CARP_SENDAD_MIN_SUCCESS) { |
1146 | carp_suppress_preempt--; | | 1144 | carp_suppress_preempt--; |
| @@ -1149,27 +1147,27 @@ carp_send_ad(void *v) | | | @@ -1149,27 +1147,27 @@ carp_send_ad(void *v) |
1149 | } else | | 1147 | } else |
1150 | sc->sc_sendad_errors = 0; | | 1148 | sc->sc_sendad_errors = 0; |
1151 | } | | 1149 | } |
1152 | } | | 1150 | } |
1153 | #endif /* INET */ | | 1151 | #endif /* INET */ |
1154 | #ifdef INET6 | | 1152 | #ifdef INET6 |
1155 | if (sc->sc_naddrs6) { | | 1153 | if (sc->sc_naddrs6) { |
1156 | struct ip6_hdr *ip6; | | 1154 | struct ip6_hdr *ip6; |
1157 | struct ifaddr *ifa; | | 1155 | struct ifaddr *ifa; |
1158 | int _s; | | 1156 | int _s; |
1159 | | | 1157 | |
1160 | MGETHDR(m, M_DONTWAIT, MT_HEADER); | | 1158 | MGETHDR(m, M_DONTWAIT, MT_HEADER); |
1161 | if (m == NULL) { | | 1159 | if (m == NULL) { |
1162 | sc->sc_if.if_oerrors++; | | 1160 | if_statinc(&sc->sc_if, if_oerrors); |
1163 | CARP_STATINC(CARP_STAT_ONOMEM); | | 1161 | CARP_STATINC(CARP_STAT_ONOMEM); |
1164 | /* XXX maybe less ? */ | | 1162 | /* XXX maybe less ? */ |
1165 | goto retry_later; | | 1163 | goto retry_later; |
1166 | } | | 1164 | } |
1167 | MCLAIM(m, &carp_proto6_mowner_tx); | | 1165 | MCLAIM(m, &carp_proto6_mowner_tx); |
1168 | len = sizeof(*ip6) + sizeof(ch); | | 1166 | len = sizeof(*ip6) + sizeof(ch); |
1169 | m->m_pkthdr.len = len; | | 1167 | m->m_pkthdr.len = len; |
1170 | m_reset_rcvif(m); | | 1168 | m_reset_rcvif(m); |
1171 | m->m_len = len; | | 1169 | m->m_len = len; |
1172 | m_align(m, m->m_len); | | 1170 | m_align(m, m->m_len); |
1173 | m->m_flags |= M_MCAST; | | 1171 | m->m_flags |= M_MCAST; |
1174 | ip6 = mtod(m, struct ip6_hdr *); | | 1172 | ip6 = mtod(m, struct ip6_hdr *); |
1175 | memset(ip6, 0, sizeof(*ip6)); | | 1173 | memset(ip6, 0, sizeof(*ip6)); |
| @@ -1183,51 +1181,50 @@ carp_send_ad(void *v) | | | @@ -1183,51 +1181,50 @@ carp_send_ad(void *v) |
1183 | _s = pserialize_read_enter(); | | 1181 | _s = pserialize_read_enter(); |
1184 | ifa = ifaof_ifpforaddr(&sa, sc->sc_carpdev); | | 1182 | ifa = ifaof_ifpforaddr(&sa, sc->sc_carpdev); |
1185 | if (ifa == NULL) /* This should never happen with IPv6 */ | | 1183 | if (ifa == NULL) /* This should never happen with IPv6 */ |
1186 | memset(&ip6->ip6_src, 0, sizeof(struct in6_addr)); | | 1184 | memset(&ip6->ip6_src, 0, sizeof(struct in6_addr)); |
1187 | else | | 1185 | else |
1188 | bcopy(ifatoia6(ifa)->ia_addr.sin6_addr.s6_addr, | | 1186 | bcopy(ifatoia6(ifa)->ia_addr.sin6_addr.s6_addr, |
1189 | &ip6->ip6_src, sizeof(struct in6_addr)); | | 1187 | &ip6->ip6_src, sizeof(struct in6_addr)); |
1190 | pserialize_read_exit(_s); | | 1188 | pserialize_read_exit(_s); |
1191 | /* set the multicast destination */ | | 1189 | /* set the multicast destination */ |
1192 | | | 1190 | |
1193 | ip6->ip6_dst.s6_addr16[0] = htons(0xff02); | | 1191 | ip6->ip6_dst.s6_addr16[0] = htons(0xff02); |
1194 | ip6->ip6_dst.s6_addr8[15] = 0x12; | | 1192 | ip6->ip6_dst.s6_addr8[15] = 0x12; |
1195 | if (in6_setscope(&ip6->ip6_dst, &sc->sc_if, NULL) != 0) { | | 1193 | if (in6_setscope(&ip6->ip6_dst, &sc->sc_if, NULL) != 0) { |
1196 | sc->sc_if.if_oerrors++; | | 1194 | if_statinc(&sc->sc_if, if_oerrors); |
1197 | m_freem(m); | | 1195 | m_freem(m); |
1198 | CARP_LOG(sc, ("in6_setscope failed")); | | 1196 | CARP_LOG(sc, ("in6_setscope failed")); |
1199 | goto retry_later; | | 1197 | goto retry_later; |
1200 | } | | 1198 | } |
1201 | | | 1199 | |
1202 | ch_ptr = (struct carp_header *)(&ip6[1]); | | 1200 | ch_ptr = (struct carp_header *)(&ip6[1]); |
1203 | memcpy(ch_ptr, &ch, sizeof(ch)); | | 1201 | memcpy(ch_ptr, &ch, sizeof(ch)); |
1204 | carp_prepare_ad(m, sc, ch_ptr); | | 1202 | carp_prepare_ad(m, sc, ch_ptr); |
1205 | | | 1203 | |
1206 | ch_ptr->carp_cksum = carp6_cksum(m, sizeof(*ip6), | | 1204 | ch_ptr->carp_cksum = carp6_cksum(m, sizeof(*ip6), |
1207 | len - sizeof(*ip6)); | | 1205 | len - sizeof(*ip6)); |
1208 | | | 1206 | |
1209 | nanotime(&sc->sc_if.if_lastchange); | | 1207 | nanotime(&sc->sc_if.if_lastchange); |
1210 | sc->sc_if.if_opackets++; | | 1208 | if_statadd2(&sc->sc_if, if_opackets, 1, if_obytes, len); |
1211 | sc->sc_if.if_obytes += len; | | | |
1212 | CARP_STATINC(CARP_STAT_OPACKETS6); | | 1209 | CARP_STATINC(CARP_STAT_OPACKETS6); |
1213 | | | 1210 | |
1214 | error = ip6_output(m, NULL, NULL, 0, &sc->sc_im6o, NULL, NULL); | | 1211 | error = ip6_output(m, NULL, NULL, 0, &sc->sc_im6o, NULL, NULL); |
1215 | if (error) { | | 1212 | if (error) { |
1216 | if (error == ENOBUFS) | | 1213 | if (error == ENOBUFS) |
1217 | CARP_STATINC(CARP_STAT_ONOMEM); | | 1214 | CARP_STATINC(CARP_STAT_ONOMEM); |
1218 | else | | 1215 | else |
1219 | CARP_LOG(sc, ("ip6_output failed: %d", error)); | | 1216 | CARP_LOG(sc, ("ip6_output failed: %d", error)); |
1220 | sc->sc_if.if_oerrors++; | | 1217 | if_statinc(&sc->sc_if, if_oerrors); |
1221 | if (sc->sc_sendad_errors < INT_MAX) | | 1218 | if (sc->sc_sendad_errors < INT_MAX) |
1222 | sc->sc_sendad_errors++; | | 1219 | sc->sc_sendad_errors++; |
1223 | if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) { | | 1220 | if (sc->sc_sendad_errors == CARP_SENDAD_MAX_ERRORS) { |
1224 | carp_suppress_preempt++; | | 1221 | carp_suppress_preempt++; |
1225 | if (carp_suppress_preempt == 1) | | 1222 | if (carp_suppress_preempt == 1) |
1226 | carp_send_ad_all(); | | 1223 | carp_send_ad_all(); |
1227 | } | | 1224 | } |
1228 | sc->sc_sendad_success = 0; | | 1225 | sc->sc_sendad_success = 0; |
1229 | } else { | | 1226 | } else { |
1230 | if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) { | | 1227 | if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) { |
1231 | if (++sc->sc_sendad_success >= | | 1228 | if (++sc->sc_sendad_success >= |
1232 | CARP_SENDAD_MIN_SUCCESS) { | | 1229 | CARP_SENDAD_MIN_SUCCESS) { |
1233 | carp_suppress_preempt--; | | 1230 | carp_suppress_preempt--; |
| @@ -1499,27 +1496,27 @@ carp_input(struct mbuf *m, u_int8_t *sho | | | @@ -1499,27 +1496,27 @@ carp_input(struct mbuf *m, u_int8_t *sho |
1499 | ether_input(&vh->sc_if, m0); | | 1496 | ether_input(&vh->sc_if, m0); |
1500 | } | | 1497 | } |
1501 | return (1); | | 1498 | return (1); |
1502 | } | | 1499 | } |
1503 | | | 1500 | |
1504 | ifp = carp_ourether(cif, &eh, m_get_rcvif_NOMPSAFE(m)->if_type, 0); | | 1501 | ifp = carp_ourether(cif, &eh, m_get_rcvif_NOMPSAFE(m)->if_type, 0); |
1505 | if (ifp == NULL) { | | 1502 | if (ifp == NULL) { |
1506 | return (1); | | 1503 | return (1); |
1507 | } | | 1504 | } |
1508 | | | 1505 | |
1509 | m_set_rcvif(m, ifp); | | 1506 | m_set_rcvif(m, ifp); |
1510 | | | 1507 | |
1511 | bpf_mtap(ifp, m, BPF_D_IN); | | 1508 | bpf_mtap(ifp, m, BPF_D_IN); |
1512 | ifp->if_ipackets++; | | 1509 | if_statinc(ifp, if_ipackets); |
1513 | ether_input(ifp, m); | | 1510 | ether_input(ifp, m); |
1514 | return (0); | | 1511 | return (0); |
1515 | } | | 1512 | } |
1516 | | | 1513 | |
1517 | static void | | 1514 | static void |
1518 | carp_master_down(void *v) | | 1515 | carp_master_down(void *v) |
1519 | { | | 1516 | { |
1520 | struct carp_softc *sc = v; | | 1517 | struct carp_softc *sc = v; |
1521 | | | 1518 | |
1522 | switch (sc->sc_state) { | | 1519 | switch (sc->sc_state) { |
1523 | case INIT: | | 1520 | case INIT: |
1524 | printf("%s: master_down event in INIT state\n", | | 1521 | printf("%s: master_down event in INIT state\n", |
1525 | sc->sc_if.if_xname); | | 1522 | sc->sc_if.if_xname); |