Index: src/sys/netinet/ip_carp.c diff -u src/sys/netinet/ip_carp.c:1.27.2.9 src/sys/netinet/ip_carp.c:1.27.2.6 --- src/sys/netinet/ip_carp.c:1.27.2.9 Wed Oct 11 02:39:38 2006 +++ src/sys/netinet/ip_carp.c Mon Dec 26 05:59:20 2005 @@ -209,7 +209,6 @@ static int carp_addrcount(struct carp_if *, struct in_ifaddr *, int); enum { CARP_COUNT_MASTER, CARP_COUNT_RUNNING }; -static void carp_multicast_cleanup(struct carp_softc *); static int carp_set_addr(struct carp_softc *, struct sockaddr_in *); static int carp_del_addr(struct carp_softc *, struct sockaddr_in *); static void carp_carpdev_state_locked(struct carp_if *); @@ -224,8 +223,6 @@ static struct mtx carp_mtx; IFC_SIMPLE_DECLARE(carp, 0); -static eventhandler_tag if_detach_event_tag; - static __inline u_int16_t carp_cksum(struct mbuf *m, int len) { @@ -375,7 +372,6 @@ #ifdef INET6 sc->sc_im6o.im6o_multicast_hlim = CARP_DFLTTL; #endif - sc->sc_imo.imo_multicast_vif = -1; callout_init(&sc->sc_ad_tmo, NET_CALLOUT_MPSAFE); callout_init(&sc->sc_md_tmo, NET_CALLOUT_MPSAFE); @@ -403,76 +399,63 @@ carp_clone_destroy(struct ifnet *ifp) { struct carp_softc *sc = ifp->if_softc; - - if (sc->sc_carpdev) - CARP_SCLOCK(sc); - carpdetach(sc); - if (sc->sc_carpdev) - CARP_SCUNLOCK(sc); - - mtx_lock(&carp_mtx); - LIST_REMOVE(sc, sc_next); - mtx_unlock(&carp_mtx); - bpfdetach(ifp); - if_detach(ifp); - if_free_type(ifp, IFT_ETHER); - free(sc, M_CARP); -} - -static void -carpdetach(struct carp_softc *sc) -{ struct carp_if *cif; + struct ip_moptions *imo = &sc->sc_imo; +#ifdef INET6 + struct ip6_moptions *im6o = &sc->sc_im6o; +#endif + +/* carpdetach(sc); */ - callout_stop(&sc->sc_ad_tmo); - callout_stop(&sc->sc_md_tmo); - callout_stop(&sc->sc_md6_tmo); - + /* + * If an interface is destroyed which is suppressing the preemption, + * decrease the global counter, otherwise the host will never get + * out of the carp supressing state. + */ if (sc->sc_suppress) carp_suppress_preempt--; sc->sc_suppress = 0; - if (sc->sc_sendad_errors >= CARP_SENDAD_MAX_ERRORS) - carp_suppress_preempt--; - sc->sc_sendad_errors = 0; + callout_stop(&sc->sc_ad_tmo); + callout_stop(&sc->sc_md_tmo); + callout_stop(&sc->sc_md6_tmo); - carp_set_state(sc, INIT); - SC2IFP(sc)->if_flags &= ~IFF_UP; - carp_setrun(sc, 0); - carp_multicast_cleanup(sc); + if (imo->imo_num_memberships) { + in_delmulti(imo->imo_membership[--imo->imo_num_memberships]); + imo->imo_multicast_ifp = NULL; + } +#ifdef INET6 + while (!LIST_EMPTY(&im6o->im6o_memberships)) { + struct in6_multi_mship *imm = + LIST_FIRST(&im6o->im6o_memberships); + LIST_REMOVE(imm, i6mm_chain); + in6_leavegroup(imm); + } + im6o->im6o_multicast_ifp = NULL; +#endif - if (sc->sc_carpdev != NULL) { - cif = (struct carp_if *)sc->sc_carpdev->if_carp; - CARP_LOCK_ASSERT(cif); + /* Remove ourself from parents if_carp queue */ + if (sc->sc_carpdev && (cif = sc->sc_carpdev->if_carp)) { + CARP_LOCK(cif); TAILQ_REMOVE(&cif->vhif_vrs, sc, sc_list); if (!--cif->vhif_nvrs) { - ifpromisc(sc->sc_carpdev, 0); sc->sc_carpdev->if_carp = NULL; CARP_LOCK_DESTROY(cif); - FREE(cif, M_IFADDR); + FREE(cif, M_CARP); + ifpromisc(sc->sc_carpdev, 0); + sc->sc_carpdev = NULL; + } else { + CARP_UNLOCK(cif); } } - sc->sc_carpdev = NULL; -} - -/* Detach an interface from the carp. */ -static void -carp_ifdetach(void *arg __unused, struct ifnet *ifp) -{ - struct carp_if *cif = (struct carp_if *)ifp->if_carp; - struct carp_softc *sc, *nextsc; - - if (cif == NULL) - return; - /* - * XXX: At the end of for() cycle the lock will be destroyed. - */ - CARP_LOCK(cif); - for (sc = TAILQ_FIRST(&cif->vhif_vrs); sc; sc = nextsc) { - nextsc = TAILQ_NEXT(sc, sc_list); - carpdetach(sc); - } + mtx_lock(&carp_mtx); + LIST_REMOVE(sc, sc_next); + mtx_unlock(&carp_mtx); + bpfdetach(ifp); + if_detach(ifp); + if_free_type(ifp, IFT_ETHER); + free(sc, M_CARP); } /* @@ -768,6 +751,42 @@ return; } +static void +carpdetach(struct carp_softc *sc) +{ + struct ifaddr *ifa; + + callout_stop(&sc->sc_ad_tmo); + callout_stop(&sc->sc_md_tmo); + callout_stop(&sc->sc_md6_tmo); + + while ((ifa = TAILQ_FIRST(&SC2IFP(sc)->if_addrlist)) != NULL) + if (ifa->ifa_addr->sa_family == AF_INET) { + struct in_ifaddr *ia = ifatoia(ifa); + + carp_del_addr(sc, &ia->ia_addr); + + /* ripped screaming from in_control(SIOCDIFADDR) */ + in_ifscrub(SC2IFP(sc), ia); + TAILQ_REMOVE(&SC2IFP(sc)->if_addrlist, ifa, ifa_link); + TAILQ_REMOVE(&in_ifaddrhead, ia, ia_link); + IFAFREE((&ia->ia_ifa)); + } +} + +/* Detach an interface from the carp. */ +void +carp_ifdetach(struct ifnet *ifp) +{ + struct carp_softc *sc; + struct carp_if *cif = (struct carp_if *)ifp->if_carp; + + CARP_LOCK(cif); + TAILQ_FOREACH(sc, &cif->vhif_vrs, sc_list) + carpdetach(sc); + CARP_UNLOCK(cif); +} + static int carp_prepare_ad(struct mbuf *m, struct carp_softc *sc, struct carp_header *ch) { @@ -965,14 +984,9 @@ sizeof(struct in6_addr)); /* set the multicast destination */ - ip6->ip6_dst.s6_addr16[0] = htons(0xff02); + ip6->ip6_dst.s6_addr8[0] = 0xff; + ip6->ip6_dst.s6_addr8[1] = 0x02; ip6->ip6_dst.s6_addr8[15] = 0x12; - if (in6_setscope(&ip6->ip6_dst, sc->sc_carpdev, NULL) != 0) { - SC2IFP(sc)->if_oerrors++; - m_freem(m); - CARP_LOG("%s: in6_setscope failed\n", __func__); - return; - } ch_ptr = (struct carp_header *)(&ip6[1]); bcopy(&ch, ch_ptr, sizeof(ch)); @@ -1293,11 +1307,7 @@ { struct timeval tv; - if (sc->sc_carpdev == NULL) { - SC2IFP(sc)->if_drv_flags &= ~IFF_DRV_RUNNING; - carp_set_state(sc, INIT); - return; - } else + if (sc->sc_carpdev) CARP_SCLOCK_ASSERT(sc); if (SC2IFP(sc)->if_flags & IFF_UP && @@ -1364,37 +1374,6 @@ } } -void -carp_multicast_cleanup(struct carp_softc *sc) -{ - struct ip_moptions *imo = &sc->sc_imo; -#ifdef INET6 - struct ip6_moptions *im6o = &sc->sc_im6o; -#endif - u_int16_t n = imo->imo_num_memberships; - - /* Clean up our own multicast memberships */ - while (n-- > 0) { - if (imo->imo_membership[n] != NULL) { - in_delmulti(imo->imo_membership[n]); - imo->imo_membership[n] = NULL; - } - } - imo->imo_num_memberships = 0; - imo->imo_multicast_ifp = NULL; - -#ifdef INET6 - while (!LIST_EMPTY(&im6o->im6o_memberships)) { - struct in6_multi_mship *imm = - LIST_FIRST(&im6o->im6o_memberships); - - LIST_REMOVE(imm, i6mm_chain); - in6_leavegroup(imm); - } - im6o->im6o_multicast_ifp = NULL; -#endif -} - static int carp_set_addr(struct carp_softc *sc, struct sockaddr_in *sin) { @@ -2155,19 +2134,16 @@ static int carp_modevent(module_t mod, int type, void *data) { + int error = 0; + switch (type) { case MOD_LOAD: - if_detach_event_tag = EVENTHANDLER_REGISTER(ifnet_departure_event, - carp_ifdetach, NULL, EVENTHANDLER_PRI_ANY); - if (if_detach_event_tag == NULL) - return (ENOMEM); mtx_init(&carp_mtx, "carp_mtx", NULL, MTX_DEF); LIST_INIT(&carpif_list); if_clone_attach(&carp_cloner); break; case MOD_UNLOAD: - EVENTHANDLER_DEREGISTER(ifnet_departure_event, if_detach_event_tag); if_clone_detach(&carp_cloner); while (!LIST_EMPTY(&carpif_list)) carp_clone_destroy(SC2IFP(LIST_FIRST(&carpif_list))); @@ -2175,10 +2151,11 @@ break; default: - return (EINVAL); + error = EINVAL; + break; } - return (0); + return error; } static moduledata_t carp_mod = { Index: src/sys/netinet/ip_fw2.c diff -u src/sys/netinet/ip_fw2.c:1.106.2.21 src/sys/netinet/ip_fw2.c:1.106.2.12 --- src/sys/netinet/ip_fw2.c:1.106.2.21 Wed Oct 11 02:39:38 2006 +++ src/sys/netinet/ip_fw2.c Thu Mar 9 21:42:44 2006 @@ -43,7 +43,6 @@ #endif #include "opt_inet6.h" #include "opt_ipsec.h" -#include "opt_mac.h" #include #include @@ -52,7 +51,6 @@ #include #include #include -#include #include #include #include @@ -73,8 +71,6 @@ #include #include #include -#include -#include #include #include #include @@ -676,11 +672,11 @@ hash_packet6(struct ipfw_flow_id *id) { u_int32_t i; - i = (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^ + i = (id->dst_ip6.__u6_addr.__u6_addr32[0]) ^ + (id->dst_ip6.__u6_addr.__u6_addr32[1]) ^ + (id->dst_ip6.__u6_addr.__u6_addr32[2]) ^ (id->dst_ip6.__u6_addr.__u6_addr32[3]) ^ - (id->src_ip6.__u6_addr.__u6_addr32[2]) ^ - (id->src_ip6.__u6_addr.__u6_addr32[3]) ^ - (id->dst_port) ^ (id->src_port); + (id->dst_port) ^ (id->src_port) ^ (id->flow_id6); return i; } @@ -816,9 +812,6 @@ if (cmd->opcode == O_PROB) cmd += F_LEN(cmd); - if (cmd->opcode == O_TAG) - cmd += F_LEN(cmd); - action = action2; switch (cmd->opcode) { case O_DENY: @@ -1452,72 +1445,62 @@ */ static int install_state(struct ip_fw *rule, ipfw_insn_limit *cmd, - struct ip_fw_args *args, uint32_t tablearg) + struct ip_fw_args *args) { static int last_log; ipfw_dyn_rule *q; - DEB( - printf("ipfw: %s: type %d 0x%08x %u -> 0x%08x %u\n", - __func__, cmd->o.opcode, + DEB(printf("ipfw: install state type %d 0x%08x %u -> 0x%08x %u\n", + cmd->o.opcode, (args->f_id.src_ip), (args->f_id.src_port), - (args->f_id.dst_ip), (args->f_id.dst_port)); - ) + (args->f_id.dst_ip), (args->f_id.dst_port) );) IPFW_DYN_LOCK(); q = lookup_dyn_rule_locked(&args->f_id, NULL, NULL); - if (q != NULL) { /* should never occur */ + if (q != NULL) { /* should never occur */ if (last_log != time_second) { last_log = time_second; - printf("ipfw: %s: entry already present, done\n", - __func__); + printf("ipfw: install_state: entry already present, done\n"); } IPFW_DYN_UNLOCK(); - return (0); + return 0; } if (dyn_count >= dyn_max) - /* Run out of slots, try to remove any expired rule. */ + /* + * Run out of slots, try to remove any expired rule. + */ remove_dyn_rule(NULL, (ipfw_dyn_rule *)1); if (dyn_count >= dyn_max) { if (last_log != time_second) { last_log = time_second; - printf("ipfw: %s: Too many dynamic rules\n", __func__); + printf("ipfw: install_state: Too many dynamic rules\n"); } IPFW_DYN_UNLOCK(); - return (1); /* cannot install, notify caller */ + return 1; /* cannot install, notify caller */ } switch (cmd->o.opcode) { - case O_KEEP_STATE: /* bidir rule */ + case O_KEEP_STATE: /* bidir rule */ add_dyn_rule(&args->f_id, O_KEEP_STATE, rule); break; - case O_LIMIT: { /* limit number of sessions */ + case O_LIMIT: /* limit number of sessions */ + { + u_int16_t limit_mask = cmd->limit_mask; struct ipfw_flow_id id; ipfw_dyn_rule *parent; - uint32_t conn_limit; - uint16_t limit_mask = cmd->limit_mask; - conn_limit = (cmd->conn_limit == IP_FW_TABLEARG) ? - tablearg : cmd->conn_limit; - - DEB( - if (cmd->conn_limit == IP_FW_TABLEARG) - printf("ipfw: %s: O_LIMIT rule, conn_limit: %u " - "(tablearg)\n", __func__, conn_limit); - else - printf("ipfw: %s: O_LIMIT rule, conn_limit: %u\n", - __func__, conn_limit); - ) + DEB(printf("ipfw: installing dyn-limit rule %d\n", + cmd->conn_limit);) - id.dst_ip = id.src_ip = id.dst_port = id.src_port = 0; + id.dst_ip = id.src_ip = 0; + id.dst_port = id.src_port = 0; id.proto = args->f_id.proto; - id.addr_type = args->f_id.addr_type; if (IS_IP6_FLOW_ID (&(args->f_id))) { if (limit_mask & DYN_SRC_ADDR) @@ -1534,40 +1517,38 @@ id.src_port = args->f_id.src_port; if (limit_mask & DYN_DST_PORT) id.dst_port = args->f_id.dst_port; - if ((parent = lookup_dyn_parent(&id, rule)) == NULL) { - printf("ipfw: %s: add parent failed\n", __func__); + parent = lookup_dyn_parent(&id, rule); + if (parent == NULL) { + printf("ipfw: add parent failed\n"); IPFW_DYN_UNLOCK(); - return (1); + return 1; } - - if (parent->count >= conn_limit) { - /* See if we can remove some expired rule. */ + if (parent->count >= cmd->conn_limit) { + /* + * See if we can remove some expired rule. + */ remove_dyn_rule(rule, parent); - if (parent->count >= conn_limit) { + if (parent->count >= cmd->conn_limit) { if (fw_verbose && last_log != time_second) { last_log = time_second; log(LOG_SECURITY | LOG_DEBUG, "drop session, too many entries\n"); } IPFW_DYN_UNLOCK(); - return (1); + return 1; } } add_dyn_rule(&args->f_id, O_LIMIT, (struct ip_fw *)parent); + } break; - } default: - printf("ipfw: %s: unknown dynamic rule type %u\n", - __func__, cmd->o.opcode); + printf("ipfw: unknown dynamic rule type %u\n", cmd->o.opcode); IPFW_DYN_UNLOCK(); - return (1); + return 1; } - - /* XXX just set lifetime */ - lookup_dyn_rule_locked(&args->f_id, NULL, NULL); - + lookup_dyn_rule_locked(&args->f_id, NULL, NULL); /* XXX just set lifetime */ IPFW_DYN_UNLOCK(); - return (0); + return 0; } /* @@ -1575,12 +1556,9 @@ * When flags & TH_RST, we are sending a RST packet, because of a * "reset" action matched the packet. * Otherwise we are sending a keepalive, and flags & TH_ - * The 'replyto' mbuf is the mbuf being replied to, if any, and is required - * so that MAC can label the reply appropriately. */ static struct mbuf * -send_pkt(struct mbuf *replyto, struct ipfw_flow_id *id, u_int32_t seq, - u_int32_t ack, int flags) +send_pkt(struct ipfw_flow_id *id, u_int32_t seq, u_int32_t ack, int flags) { struct mbuf *m; struct ip *ip; @@ -1590,16 +1568,6 @@ if (m == 0) return (NULL); m->m_pkthdr.rcvif = (struct ifnet *)0; - -#ifdef MAC - if (replyto != NULL) - mac_create_mbuf_netlayer(replyto, m); - else - mac_create_mbuf_from_firewall(m); -#else - (void)replyto; /* don't warn about unused arg */ -#endif - m->m_pkthdr.len = m->m_len = sizeof(struct ip) + sizeof(struct tcphdr); m->m_data += max_linkhdr; @@ -1684,8 +1652,8 @@ L3HDR(struct tcphdr, mtod(args->m, struct ip *)); if ( (tcp->th_flags & TH_RST) == 0) { struct mbuf *m; - m = send_pkt(args->m, &(args->f_id), - ntohl(tcp->th_seq), ntohl(tcp->th_ack), + m = send_pkt(&(args->f_id), ntohl(tcp->th_seq), + ntohl(tcp->th_ack), tcp->th_flags | TH_RST); if (m != NULL) ip_output(m, NULL, NULL, 0, NULL, NULL); @@ -1723,8 +1691,6 @@ cmd += F_LEN(cmd); if (cmd->opcode == O_ALTQ) cmd += F_LEN(cmd); - if (cmd->opcode == O_TAG) - cmd += F_LEN(cmd); if ( cmd->opcode == O_SKIPTO ) for (rule = me->next; rule ; rule = rule->next) if (rule->rulenum >= cmd->arg1) @@ -2237,10 +2203,7 @@ case IPPROTO_ROUTING: /* RFC 2460 */ PULLUP_TO(hlen, ulp, struct ip6_rthdr); - switch (((struct ip6_rthdr *)ulp)->ip6r_type) { - case 0: - break; - default: + if (((struct ip6_rthdr *)ulp)->ip6r_type != 0) { printf("IPFW2: IPV6 - Unknown Routing " "Header type(%d)\n", ((struct ip6_rthdr *)ulp)->ip6r_type); @@ -2311,35 +2274,11 @@ PULLUP_TO(hlen, ulp, struct ip6_ext); break; - case IPPROTO_PIM: - /* XXX PIM header check? */ - PULLUP_TO(hlen, ulp, struct pim); - break; - - case IPPROTO_CARP: - PULLUP_TO(hlen, ulp, struct carp_header); - if (((struct carp_header *)ulp)->carp_version != - CARP_VERSION) - return (IP_FW_DENY); - if (((struct carp_header *)ulp)->carp_type != - CARP_ADVERTISEMENT) - return (IP_FW_DENY); - break; - - case IPPROTO_IPV6: /* RFC 2893 */ - PULLUP_TO(hlen, ulp, struct ip6_hdr); - break; - - case IPPROTO_IPV4: /* RFC 2893 */ - PULLUP_TO(hlen, ulp, struct ip); - break; - default: printf("IPFW2: IPV6 - Unknown Extension " "Header(%d), ext_hd=%x\n", proto, ext_hd); if (fw_deny_unknown_exthdrs) return (IP_FW_DENY); - PULLUP_TO(hlen, ulp, struct ip6_ext); break; } /*switch */ } @@ -2931,25 +2870,22 @@ &((ipfw_insn_ip6 *)cmd)->addr6); break; case O_IP6_SRC_MASK: + if (is_ipv6) { + ipfw_insn_ip6 *te = (ipfw_insn_ip6 *)cmd; + struct in6_addr p = args->f_id.src_ip6; + + APPLY_MASK(&p, &te->mask6); + match = IN6_ARE_ADDR_EQUAL(&te->addr6, &p); + } + break; + case O_IP6_DST_MASK: if (is_ipv6) { - int i = cmdlen - 1; - struct in6_addr p; - struct in6_addr *d = - &((ipfw_insn_ip6 *)cmd)->addr6; - - for (; !match && i > 0; d += 2, - i -= F_INSN_SIZE(struct in6_addr) - * 2) { - p = (cmd->opcode == - O_IP6_SRC_MASK) ? - args->f_id.src_ip6: - args->f_id.dst_ip6; - APPLY_MASK(&p, &d[1]); - match = - IN6_ARE_ADDR_EQUAL(&d[0], - &p); - } + ipfw_insn_ip6 *te = (ipfw_insn_ip6 *)cmd; + struct in6_addr p = args->f_id.dst_ip6; + + APPLY_MASK(&p, &te->mask6); + match = IN6_ARE_ADDR_EQUAL(&te->addr6, &p); } break; @@ -2981,62 +2917,6 @@ match = is_ipv4; break; - case O_TAG: { - uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ? - tablearg : cmd->arg1; - - /* Packet is already tagged with this tag? */ - mtag = m_tag_locate(m, MTAG_IPFW, tag, NULL); - - /* We have `untag' action when F_NOT flag is - * present. And we must remove this mtag from - * mbuf and reset `match' to zero (`match' will - * be inversed later). - * Otherwise we should allocate new mtag and - * push it into mbuf. - */ - if (cmd->len & F_NOT) { /* `untag' action */ - if (mtag != NULL) - m_tag_delete(m, mtag); - } else if (mtag == NULL) { - if ((mtag = m_tag_alloc(MTAG_IPFW, - tag, 0, M_NOWAIT)) != NULL) - m_tag_prepend(m, mtag); - } - match = (cmd->len & F_NOT) ? 0: 1; - break; - } - - case O_TAGGED: { - uint32_t tag = (cmd->arg1 == IP_FW_TABLEARG) ? - tablearg : cmd->arg1; - - if (cmdlen == 1) { - match = m_tag_locate(m, MTAG_IPFW, - tag, NULL) != NULL; - break; - } - - /* we have ranges */ - for (mtag = m_tag_first(m); - mtag != NULL && !match; - mtag = m_tag_next(m, mtag)) { - uint16_t *p; - int i; - - if (mtag->m_tag_cookie != MTAG_IPFW) - continue; - - p = ((ipfw_insn_u16 *)cmd)->ports; - i = cmdlen - 1; - for(; !match && i > 0; i--, p += 2) - match = - mtag->m_tag_id >= p[0] && - mtag->m_tag_id <= p[1]; - } - break; - } - /* * The second set of opcodes represents 'actions', * i.e. the terminal part of a rule once the packet @@ -3056,7 +2936,7 @@ * or to the SKIPTO target ('goto again' after * having set f, cmd and l), respectively. * - * O_TAG, O_LOG and O_ALTQ action parameters: + * O_LOG and O_ALTQ action parameters: * perform some action and set match = 1; * * O_LIMIT and O_KEEP_STATE: these opcodes are @@ -3081,7 +2961,7 @@ case O_LIMIT: case O_KEEP_STATE: if (install_state(f, - (ipfw_insn_limit *)cmd, args, tablearg)) { + (ipfw_insn_limit *)cmd, args)) { retval = IP_FW_DENY; goto done; /* error/limit violation */ } @@ -3707,7 +3587,6 @@ case O_IP6: #endif case O_IP4: - case O_TAG: if (cmdlen != F_INSN_SIZE(ipfw_insn)) goto bad_size; break; @@ -3780,7 +3659,6 @@ case O_IPTTL: case O_IPLEN: case O_TCPDATALEN: - case O_TAGGED: if (cmdlen < 1 || cmdlen > 31) goto bad_size; break; @@ -4063,10 +3941,9 @@ IPFW_WLOCK(&layer3_chain); layer3_chain.reap = NULL; free_chain(&layer3_chain, 0 /* keep default rule */); - rule = layer3_chain.reap; - layer3_chain.reap = NULL; + rule = layer3_chain.reap, layer3_chain.reap = NULL; IPFW_WUNLOCK(&layer3_chain); - if (rule != NULL) + if (layer3_chain.reap != NULL) reap_rules(rule); break; @@ -4192,6 +4069,10 @@ } size = sopt->sopt_valsize; tbl = malloc(size, M_TEMP, M_WAITOK); + if (tbl == NULL) { + error = ENOMEM; + break; + } error = sooptcopyin(sopt, tbl, size, sizeof(*tbl)); if (error) { free(tbl, M_TEMP); @@ -4266,11 +4147,11 @@ if (TIME_LEQ(q->expire, time_second)) continue; /* too late, rule expired */ - *mtailp = send_pkt(NULL, &(q->id), q->ack_rev - 1, + *mtailp = send_pkt(&(q->id), q->ack_rev - 1, q->ack_fwd, TH_SYN); if (*mtailp != NULL) mtailp = &(*mtailp)->m_nextpkt; - *mtailp = send_pkt(NULL, &(q->id), q->ack_fwd - 1, + *mtailp = send_pkt(&(q->id), q->ack_fwd - 1, q->ack_rev, 0); if (*mtailp != NULL) mtailp = &(*mtailp)->m_nextpkt; Index: src/sys/netinet/ip_carp.h diff -u src/sys/netinet/ip_carp.h:1.1.4.1 src/sys/netinet/ip_carp.h:1.1 --- src/sys/netinet/ip_carp.h:1.1.4.1 Thu Aug 10 18:10:12 2006 +++ src/sys/netinet/ip_carp.h Tue Feb 22 21:04:03 2005 @@ -148,6 +148,7 @@ } #ifdef _KERNEL +void carp_ifdetach (struct ifnet *); void carp_carpdev_state(void *); void carp_input (struct mbuf *, int); int carp6_input (struct mbuf **, int *, int);