Lines Matching defs:is

203 /* other functions is obvious.                                              */
218 /* other functions is obvious. */
337 /* Initialise the state soft context structure so it is ready for use. */
438 ipstate_t *is;
440 while ((is = softs->ipf_state_list) != NULL)
441 ipf_state_del(softc, is, ISL_UNLOAD);
445 * exist on the state list, appr_unload is called after
448 * There's no real justification as this is the only complication.
852 /* there is a filter rule associated with the state entry, copy that out */
853 /* as well. The entry to copy out is taken from the value of "ips_next" in */
863 ipstate_t *is, *isn;
889 for (is = softs->ipf_state_list; is; is = is->is_next)
890 if (is == isn)
892 if (!is) {
928 ipstate_t *is, *isn;
1032 for (is = softs->ipf_state_list; is; is = is->is_next)
1033 if (is->is_rule == fr) {
1039 if (is == NULL) {
1059 /* Parameters: is(I) - pointer to state structure */
1069 /* Locking: it is assumed that some kind of lock on ipf_state is held. */
1073 ipf_state_insert(softc, is, rev)
1075 ipstate_t *is;
1087 if (is->is_ifp[i] != NULL)
1089 is->is_ifp[i] = ipf_resolvenic(softc, is->is_ifname[i],
1090 is->is_v);
1097 hv = is->is_hv % softs->ipf_state_size;
1098 /* TRACE is, hv */
1099 is->is_hv = hv;
1102 * We need to get both of these locks...the first because it is
1103 * possible that once the insert is complete another packet might
1106 MUTEX_INIT(&is->is_lock, "ipf state entry");
1107 MUTEX_ENTER(&is->is_lock);
1110 fr = is->is_rule;
1114 is->is_family, &is->is_src) == -1)) {
1126 if (is->is_flags & (SI_WILDP|SI_WILDA)) {
1131 SBUMP(ipf_state_stats.iss_proto[is->is_p]);
1132 SBUMP(ipf_state_stats.iss_active_proto[is->is_p]);
1138 softs->ipf_state_list->is_pnext = &is->is_next;
1139 is->is_pnext = &softs->ipf_state_list;
1140 is->is_next = softs->ipf_state_list;
1141 softs->ipf_state_list = is;
1144 softs->ipf_state_table[hv]->is_phnext = &is->is_hnext;
1147 is->is_phnext = softs->ipf_state_table + hv;
1148 is->is_hnext = softs->ipf_state_table[hv];
1149 softs->ipf_state_table[hv] = is;
1154 ipf_state_setqueue(softc, is, rev);
1167 /* even there is only reverse match */
1196 /* even there is only reverse match */
1229 /* the state is established by packet flying from .1 to .2 so we see: */
1234 /* temporal record, is2 is initialized as follows: */
1372 /* the call will fail and a flush is scheduled for the next timeout call. */
1387 ipstate_t *is, ips;
1396 * If a locally created packet is trying to egress but it
1397 * does not match because of this lock, it is likely that
1399 * up the stack. To mitigate this error, EAGAIN is returned instead,
1427 * fr it is possible that we could overflow. The cost of overflowing
1428 * is being ignored here as the number by which it can overflow is
1447 is = &ips;
1450 is->is_tag = FR_NOLOGTAG;
1458 bzero((char *)is, sizeof(*is));
1459 is->is_die = 1 + softc->ipf_ticks;
1461 * We want to check everything that is a property of this packet,
1465 is->is_pass = pass;
1466 is->is_v = fin->fin_v;
1467 is->is_sec = fin->fin_secmsk;
1468 is->is_secmsk = 0xffff;
1469 is->is_auth = fin->fin_auth;
1470 is->is_authmsk = 0xffff;
1471 is->is_family = fin->fin_family;
1472 is->is_opt[0] = fin->fin_optmsk;
1473 is->is_optmsk[0] = 0xffffffff;
1474 if (is->is_v == 6) {
1475 is->is_opt[0] &= ~0x8;
1476 is->is_optmsk[0] &= ~0x8;
1482 hv = (is->is_p = fin->fin_fi.fi_p);
1483 is->is_src = fin->fin_fi.fi_src;
1484 hv += is->is_saddr;
1485 is->is_dst = fin->fin_fi.fi_dst;
1486 hv += is->is_daddr;
1490 * For ICMPv6, we check to see if the destination address is
1491 * a multicast address. If it is, do not include it in the
1495 if ((is->is_p == IPPROTO_ICMPV6) &&
1496 IN6_IS_ADDR_MULTICAST(&is->is_dst.in6)) {
1505 hv -= is->is_daddr;
1507 hv += is->is_dst.i6[1];
1508 hv += is->is_dst.i6[2];
1509 hv += is->is_dst.i6[3];
1511 hv += is->is_src.i6[1];
1512 hv += is->is_src.i6[2];
1513 hv += is->is_src.i6[3];
1519 hv -= is->is_daddr;
1522 switch (is->is_p)
1531 hv += (is->is_icmp.ici_id = ic->icmp_id);
1537 is->is_icmp.ici_type = ic->icmp_type;
1554 is->is_icmp.ici_type = ic->icmp_type;
1555 hv += (is->is_icmp.ici_id = ic->icmp_id);
1567 is->is_gre.gs_flags = gre->gr_flags;
1568 is->is_gre.gs_ptype = gre->gr_ptype;
1569 if (GRE_REV(is->is_gre.gs_flags) == 1) {
1570 is->is_call[0] = fin->fin_data[0];
1571 is->is_call[1] = fin->fin_data[1];
1584 /* TRACE is, flags, hv */
1590 is->is_sport = htons(fin->fin_data[0]);
1591 is->is_dport = htons(fin->fin_data[1]);
1593 hv += is->is_sport;
1594 hv += is->is_dport;
1597 /* TRACE is, flags, hv */
1600 * If this is a real packet then initialise fields in the
1604 is->is_maxdwin = 1;
1605 is->is_maxswin = ntohs(tcp->th_win);
1606 if (is->is_maxswin == 0)
1607 is->is_maxswin = 1;
1610 is->is_send = ntohl(tcp->th_seq) + fin->fin_dlen -
1614 is->is_maxsend = is->is_send;
1617 * Window scale option is only present in
1624 &is->is_tcp.ts_data[0]) == -1)
1629 ipf_checknewisn(fin, is);
1630 ipf_fixoutisn(fin, is);
1636 is->is_maxdwin = is->is_maxswin * 2;
1637 is->is_dend = ntohl(tcp->th_ack);
1638 is->is_maxdend = ntohl(tcp->th_ack);
1639 is->is_maxdwin *= 2;
1653 is->is_sport = htons(fin->fin_data[0]);
1654 is->is_dport = htons(fin->fin_data[1]);
1665 is->is_hv = hv;
1670 for (is = softs->ipf_state_table[hv % softs->ipf_state_size];
1671 is != NULL; is = is->is_hnext) {
1672 if (ipf_state_match(&ips, is) == 1)
1675 if (is != NULL) {
1689 KMALLOC(is, ipstate_t *);
1690 if (is == NULL) {
1694 bcopy((char *)&ips, (char *)is, sizeof(*is));
1695 is->is_flags = flags & IS_INHERITED;
1696 is->is_rulen = fin->fin_rule;
1697 is->is_rule = fr;
1700 * Do not do the modulus here, it is done in ipf_state_insert().
1705 (void) strncpy(is->is_group, FR_NAME(fr, fr_group),
1711 is->is_tqehead[0] = tq;
1712 is->is_sti.tqe_flags |= TQE_RULEBASED;
1718 is->is_tqehead[1] = tq;
1719 is->is_sti.tqe_flags |= TQE_RULEBASED;
1722 is->is_tag = fr->fr_logtag;
1726 * It may seem strange to set is_ref to 2, but if stsave is not NULL
1727 * then a copy of the pointer is being stored somewhere else and in
1730 is->is_me = stsave;
1732 *stsave = is;
1733 is->is_ref = 2;
1735 is->is_ref = 1;
1737 is->is_pkts[0] = 0, is->is_bytes[0] = 0;
1738 is->is_pkts[1] = 0, is->is_bytes[1] = 0;
1739 is->is_pkts[2] = 0, is->is_bytes[2] = 0;
1740 is->is_pkts[3] = 0, is->is_bytes[3] = 0;
1742 is->is_pkts[out] = 1;
1744 is->is_bytes[out] = fin->fin_plen;
1745 is->is_flx[out][0] = fin->fin_flx & FI_CMP;
1746 is->is_flx[out][0] &= ~FI_OOW;
1750 is->is_flags |= IS_LOOSE;
1753 is->is_flags |= IS_STRICT;
1756 is->is_flags |= IS_STATESYNC;
1759 is->is_pass &= ~(FR_LOGFIRST|FR_LOG);
1763 if (ipf_state_insert(softc, is, fin->fin_rev) == -1) {
1766 * This is a bit more manual than it should be but
1769 MUTEX_EXIT(&is->is_lock);
1770 MUTEX_DESTROY(&is->is_lock);
1771 if (is->is_tqehead[0] != NULL) {
1772 if (ipf_deletetimeoutqueue(is->is_tqehead[0]) == 0)
1773 ipf_freetimeoutqueue(softc, is->is_tqehead[0]);
1774 is->is_tqehead[0] = NULL;
1776 if (is->is_tqehead[1] != NULL) {
1777 if (ipf_deletetimeoutqueue(is->is_tqehead[1]) == 0)
1778 ipf_freetimeoutqueue(softc, is->is_tqehead[1]);
1779 is->is_tqehead[1] = NULL;
1781 KFREE(is);
1786 * Filling in the interface name is after the insert so that an
1787 * event (such as add/delete) of an interface that is referenced
1792 * The name '-' is special for network interfaces and causes
1800 is->is_ifp[out << 1] = fr->fr_ifas[0];
1801 strncpy(is->is_ifname[out << 1],
1805 is->is_ifp[out << 1] = fin->fin_ifp;
1807 is->is_ifname[out << 1]);
1810 is->is_ifp[(out << 1) + 1] = fr->fr_ifas[1];
1812 strncpy(is->is_ifname[(out << 1) + 1],
1817 is->is_ifp[(1 - out) << 1] = fr->fr_ifas[2];
1819 strncpy(is->is_ifname[((1 - out) << 1)],
1824 is->is_ifp[((1 - out) << 1) + 1] = fr->fr_ifas[3];
1826 strncpy(is->is_ifname[((1 - out) << 1) + 1],
1832 is->is_ifp[out << 1] = fin->fin_ifp;
1834 is->is_ifname[out << 1]);
1844 (void) ipf_tcp_age(&is->is_sti, fin, softs->ipf_state_tcptq,
1845 is->is_flags, 2);
1847 MUTEX_EXIT(&is->is_lock);
1848 if ((is->is_flags & IS_STATESYNC) && ((is->is_flags & SI_CLONE) == 0))
1849 is->is_sync = ipf_sync_new(softc, SMC_STATE, fin, is);
1851 ipf_state_log(softc, is, ISL_NEW);
1862 &is->is_tifs[0]);
1864 bcopy(fdp, &is->is_tifs[0], sizeof(*fdp));
1870 &is->is_tifs[1]);
1872 bcopy(fdp, &is->is_tifs[1], sizeof(*fdp));
1874 fin->fin_tif = &is->is_tifs[fin->fin_rev];
1879 &is->is_dif);
1881 bcopy(fdp, &is->is_dif, sizeof(*fdp));
1883 fin->fin_dif = &is->is_dif;
2002 /* is(I) - pointer to master state structure */
2005 /* Change timeout depending on whether new packet is a SYN-ACK returning */
2009 ipf_state_tcp(softc, softs, fin, tcp, is)
2014 ipstate_t *is;
2020 if (((is->is_flags & IS_TCPFSM) != 0) && (source == 1) &&
2021 (ntohs(is->is_sport) != fin->fin_data[0]))
2023 fdata = &is->is_tcp.ts_data[!source];
2024 tdata = &is->is_tcp.ts_data[source];
2026 MUTEX_ENTER(&is->is_lock);
2029 * If a SYN packet is received for a connection that is on the way out
2033 if ((is->is_state[0] > IPF_TCPS_ESTABLISHED) &&
2034 (is->is_state[1] > IPF_TCPS_ESTABLISHED)) {
2035 is->is_state[!source] = IPF_TCPS_CLOSED;
2036 ipf_movequeue(softc->ipf_ticks, &is->is_sti,
2037 is->is_sti.tqe_ifq,
2039 MUTEX_EXIT(&is->is_lock);
2040 DT1(iss_tcp_closing, ipstate_t *, is);
2046 if (is->is_flags & IS_LOOSE)
2050 is->is_flags);
2055 ret = ipf_tcp_age(&is->is_sti, fin, softs->ipf_state_tcptq,
2056 is->is_flags, ret);
2058 MUTEX_EXIT(&is->is_lock);
2059 DT2(iss_tcp_fsm, fr_info_t *, fin, ipstate_t *, is);
2065 ipf_state_log(softc, is, ISL_STATECHANGE);
2072 * Window scale option is only present in SYN/SYN-ACK packet.
2077 is->is_s0[source] = ntohl(tcp->th_ack);
2078 is->is_s0[!source] = ntohl(tcp->th_seq) + 1;
2084 if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
2085 ipf_checknewisn(fin, is);
2087 is->is_s0[source] = ntohl(tcp->th_seq) + 1;
2094 if ((fin->fin_out != 0) && (is->is_pass & FR_NEWISN))
2095 ipf_checknewisn(fin, is);
2100 DT2(iss_tcp_oow, fr_info_t *, fin, ipstate_t *, is);
2104 MUTEX_EXIT(&is->is_lock);
2113 /* is(I) - pointer to master state structure */
2115 /* Check to see if this TCP connection is expecting and needs a new */
2122 ipf_checknewisn(fin, is)
2124 ipstate_t *is;
2133 if (((i == 0) && !(is->is_flags & IS_ISNSYN)) ||
2134 ((i == 1) && !(is->is_flags & IS_ISNACK))) {
2137 is->is_isninc[i] = new - old;
2139 is->is_sumd[i] = (sumd & 0xffff) + (sumd >> 16);
2141 is->is_flags |= ((i == 0) ? IS_ISNSYN : IS_ISNACK);
2154 /* Given a packet has matched addresses and ports, check to see if it is */
2193 * if window scaling is present, the scaling is only allowed
2195 * window is 65535 to specify the largest window possible
2256 * window if SACK is in use.
2280 * packet seen from a direction that is new should be
2303 * packets. There is no way to know the length of the
2308 * state cache (and source and destination is the only stuff
2309 * that is saved in the fragment cache). Note further that
2313 * Thus, when ackskew is negative but still seems to belong
2340 /* is(I) - pointer to master state structure */
2345 ipf_state_clone(fin, tcp, is)
2348 ipstate_t *is;
2365 bcopy((char *)is, (char *)clone, sizeof(*clone));
2370 * all of that data is zero'd out.
2415 if (is->is_flags & IS_STATESYNC)
2417 DT2(iss_clone, ipstate_t *, is, ipstate_t *, clone);
2427 /* is(I) - pointer to state structure */
2433 /* Match a state table entry against an IP packet. The logic below is that */
2434 /* ret gets set to one if the match succeeds, else remains 0. If it is */
2438 ipf_matchsrcdst(fin, is, src, dst, tcp, cmask)
2440 ipstate_t *is;
2453 * If a connection is about to be deleted, no packets
2456 if (is->is_sti.tqe_ifq == &softs->ipf_state_deletetq)
2459 rev = IP6_NEQ(&is->is_dst, dst);
2462 flags = is->is_flags;
2472 if (!(flags & SI_W_SPORT) && (sp != is->is_sport))
2474 else if (!(flags & SI_W_DPORT) && (dp != is->is_dport))
2482 * If the interface for this 'direction' is set, make sure it matches.
2483 * An interface name that is not set matches any, as does a name of *.
2485 if ((is->is_ifp[idx] == ifp) || (is->is_ifp[idx] == NULL &&
2486 (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '-' ||
2487 *is->is_ifname[idx] == '*')))
2491 DT2(iss_lookup_badifp, fr_info_t *, fin, ipstate_t *, is);
2493 /* TRACE is, out, rev, idx */
2502 if ((IP6_EQ(&is->is_dst, dst) || (flags & SI_W_DADDR)) &&
2503 (IP6_EQ(&is->is_src, src) || (flags & SI_W_SADDR))) {
2505 if ((sp == is->is_sport || flags & SI_W_SPORT)
2507 (dp == is->is_dport || flags & SI_W_DPORT))
2514 if ((IP6_EQ(&is->is_dst, src) || (flags & SI_W_DADDR)) &&
2515 (IP6_EQ(&is->is_src, dst) || (flags & SI_W_SADDR))) {
2517 if ((dp == is->is_sport || flags & SI_W_SPORT)
2519 (sp == is->is_dport || flags & SI_W_DPORT))
2529 DT2(iss_lookup_badport, fr_info_t *, fin, ipstate_t *, is);
2530 /* TRACE rev, is, sp, dp, src, dst */
2535 * Whether or not this should be here, is questionable, but the aim
2536 * is to get this out of the main line.
2539 flags = is->is_flags & ~(SI_WILDP|SI_NEWFR|SI_CLONE|SI_CLONED);
2544 * For IPv6, if the address being copied in is multicast, then
2553 is->is_src = fi->fi_src;
2554 is->is_flags &= ~SI_W_SADDR;
2557 is->is_src = fi->fi_dst;
2558 is->is_flags &= ~SI_W_SADDR;
2564 is->is_dst = fi->fi_dst;
2565 is->is_flags &= ~SI_W_DADDR;
2568 is->is_dst = fi->fi_src;
2569 is->is_flags &= ~SI_W_DADDR;
2572 if ((is->is_flags & (SI_WILDA|SI_WILDP)) == 0) {
2578 cflx = is->is_flx[out][rev];
2584 ((fin->fin_optmsk & is->is_optmsk[rev]) != is->is_opt[rev]) ||
2585 ((fin->fin_secmsk & is->is_secmsk) != is->is_sec) ||
2586 ((fin->fin_auth & is->is_authmsk) != is->is_auth)) {
2593 return is;
2605 clone = ipf_state_clone(fin, tcp, is);
2608 is = clone;
2615 is->is_sport = sp;
2616 is->is_send = ntohl(tcp->th_seq);
2618 is->is_sport = dp;
2619 is->is_send = ntohl(tcp->th_ack);
2621 is->is_maxsend = is->is_send + 1;
2624 is->is_dport = dp;
2625 is->is_dend = ntohl(tcp->th_ack);
2627 is->is_dport = sp;
2628 is->is_dend = ntohl(tcp->th_seq);
2630 is->is_maxdend = is->is_dend + 1;
2632 is->is_flags &= ~(SI_W_SPORT|SI_W_DPORT);
2634 ipf_state_log(softc, is, ISL_CLONE);
2639 if (is->is_flx[out][rev] == 0) {
2640 is->is_flx[out][rev] = flx;
2641 if (rev == 1 && is->is_optmsk[1] == 0) {
2642 is->is_opt[1] = fin->fin_optmsk;
2643 is->is_optmsk[1] = 0xffffffff;
2644 if (is->is_v == 6) {
2645 is->is_opt[1] &= ~0x8;
2646 is->is_optmsk[1] &= ~0x8;
2652 * Check if the interface name for this "direction" is set and if not,
2655 if (is->is_ifp[idx] == NULL &&
2656 (*is->is_ifname[idx] == '\0' || *is->is_ifname[idx] == '*')) {
2657 is->is_ifp[idx] = ifp;
2658 COPYIFNAME(fin->fin_v, ifp, is->is_ifname[idx]);
2661 return is;
2673 /* If we return NULL then no lock on ipf_state is held. */
2674 /* If we return non-null then a read-lock on ipf_state is held. */
2682 ipstate_t *is, **isp;
2712 * 8 bytes of payload is present.
2731 * header claimed in the encapsulated part which is of concern. It
2734 * This is possible because we don't know how big oip_hl is when we
2735 * do the pullup early in ipf_check() and thus can't guarantee it is
2770 * but this is the cleanest way. Note further we fill
2774 * watch out here, as ip is in host order and oip in network
2834 ((is = *isp) != NULL); ) {
2835 isp = &is->is_hnext;
2836 if ((is->is_p != pr) || (is->is_v != 4))
2838 if (is->is_pass & FR_NOICMPERR)
2841 is = ipf_matchsrcdst(&ofin, is, &src, &dst,
2843 if ((is != NULL) && !ipf_allowstateicmp(fin, is, &src))
2844 return is;
2864 for (isp = &softs->ipf_state_table[hv]; ((is = *isp) != NULL); ) {
2865 isp = &is->is_hnext;
2873 * short flag is set.
2875 if ((is->is_p == pr) && (is->is_v == 4) &&
2876 (is = ipf_matchsrcdst(&ofin, is, &src, &dst,
2878 if (ipf_allowstateicmp(fin, is, &src) == 0)
2879 return is;
2892 /* is(I) - pointer to state table entry */
2900 ipf_allowstateicmp(fin, is, src)
2902 ipstate_t *is;
2914 fr = is->is_rule;
2934 backward = IP6_NEQ(&is->is_src, src);
2939 if (is->is_pass & FR_NOICMPERR) {
2943 if (is->is_icmppkts[i] > is->is_pkts[oi]) {
2948 DT2(iss_icmp_hits, fr_info_t *, fin, ipstate_t *, is);
2950 is->is_icmppkts[i]++;
2955 * It remains to be seen if that is correct. XXX
2964 /* Parameters: is(I) - pointer to state table entry */
2971 ipf_ipsmove(softs, is, hv)
2973 ipstate_t *is;
2979 hvm = is->is_hv;
2981 /* TRACE is, is_hv, hvm */
2986 isp = is->is_phnext;
2987 if (is->is_hnext)
2988 is->is_hnext->is_phnext = isp;
2989 *isp = is->is_hnext;
2998 is->is_hv = hvm;
3000 /* TRACE is, hv, is_hv, hvm */
3004 (*isp)->is_phnext = &is->is_hnext;
3008 is->is_phnext = isp;
3009 is->is_hnext = *isp;
3010 *isp = is;
3017 /* else pointer to state information is returned */
3023 /* the contents of *fin. For certain protocols, when a match is found the */
3024 /* timeout queue is also selected and stored in ifpq if it is non-NULL. */
3026 /* If we return NULL then no lock on ipf_state is held. */
3027 /* If we return non-null then a read-lock on ipf_state is held. */
3038 ipstate_t *is, **isp;
3045 is = NULL;
3101 ((is = *isp) != NULL); ) {
3102 isp = &is->is_hnext;
3103 if ((is->is_p != pr) || (is->is_v != v))
3105 is = ipf_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP);
3106 if (is != NULL &&
3107 ipf_matchicmpqueryreply(v, &is->is_icmp,
3117 if (is != NULL) {
3118 if ((tryagain != 0) && !(is->is_flags & SI_W_DADDR)) {
3123 ipf_ipsmove(softs, is, hv);
3131 * No matching icmp state entry. Perhaps this is a
3134 * XXX With some ICMP6 packets, the "other" address is already
3138 * to handle the specific types where that is the case.
3152 is = ipf_checkicmp6matchingstate(fin);
3153 if (is != NULL)
3154 return is;
3165 ((is = *isp) != NULL); ) {
3166 isp = &is->is_hnext;
3167 if ((is->is_p != pr) || (is->is_v != v))
3169 is = ipf_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP);
3170 if ((is != NULL) &&
3171 (ic->icmp_id == is->is_icmp.ici_id) &&
3172 ipf_matchicmpqueryreply(v, &is->is_icmp,
3181 if (is == NULL) {
3202 ((is = *isp) != NULL); ) {
3203 isp = &is->is_hnext;
3204 if ((is->is_p != pr) || (is->is_v != v))
3207 is = ipf_matchsrcdst(fin, is, &src, &dst, tcp, FI_CMP);
3208 if (is != NULL) {
3211 tcp, is)) {
3219 if (is != NULL) {
3221 !(is->is_flags & (SI_CLONE|SI_WILDP|SI_WILDA))) {
3224 ipf_ipsmove(softs, is, hv);
3239 * If we try to pretend this is a reply to a
3274 ((is = *isp) != NULL); ) {
3275 isp = &is->is_hnext;
3276 if ((is->is_p != pr) || (is->is_v != v))
3278 is = ipf_matchsrcdst(fin, is, &src, &dst, NULL, FI_CMP);
3279 if (is != NULL) {
3284 if (is == NULL) {
3290 if (is != NULL) {
3291 if (((is->is_sti.tqe_flags & TQE_RULEBASED) != 0) &&
3292 (is->is_tqehead[fin->fin_rev] != NULL))
3293 ifq = is->is_tqehead[fin->fin_rev];
3299 return is;
3310 /* Check if a packet is associated with an entry in the state table. */
3320 ipstate_t *is;
3349 is = ipf_state_lookup(fin, tcp, &ifq);
3355 if (is != NULL)
3358 is = ipf_checkicmp6matchingstate(fin);
3363 if (is != NULL)
3366 * No matching icmp state entry. Perhaps this is a
3369 is = ipf_checkicmpmatchingstate(fin);
3373 if (is == NULL)
3376 if (is->is_pass & FR_NEWISN) {
3378 ipf_fixinisn(fin, is);
3380 ipf_fixoutisn(fin, is);
3390 if (is == NULL) {
3395 fr = is->is_rule;
3414 fin->fin_rule = is->is_rulen;
3418 * If this packet is a fragment and the rule says to track fragments,
3421 if (fin->fin_flx & FI_FRAG && FR_ISPASS(is->is_pass) &&
3422 is->is_pass & FR_KEEPFRAG)
3423 (void) ipf_frag_new(softc, fin, is->is_pass);
3427 * queue is different to the last one it was on and move it if so.
3429 tqe = &is->is_sti;
3431 ifq = is->is_tqehead[fin->fin_rev];
3433 MUTEX_ENTER(&is->is_lock);
3439 is->is_pkts[inout]++;
3440 is->is_bytes[inout] += fin->fin_plen;
3441 fin->fin_pktnum = is->is_pkts[inout] + is->is_icmppkts[inout];
3443 MUTEX_EXIT(&is->is_lock);
3445 pass = is->is_pass;
3447 if (is->is_flags & IS_STATESYNC)
3448 ipf_sync_update(softc, SMC_STATE, fin, is->is_sync);
3454 fin->fin_dif = &is->is_dif;
3455 fin->fin_tif = &is->is_tifs[fin->fin_rev];
3468 /* is(I) - pointer to master state structure */
3474 ipf_fixoutisn(fin, is)
3476 ipstate_t *is;
3484 if ((is->is_flags & IS_ISNSYN) != 0) {
3487 seq += is->is_isninc[0];
3489 ipf_fix_outcksum(0, &tcp->th_sum, is->is_sumd[0], 0);
3492 if ((is->is_flags & IS_ISNACK) != 0) {
3495 seq += is->is_isninc[1];
3497 ipf_fix_outcksum(0, &tcp->th_sum, is->is_sumd[1], 0);
3507 /* is(I) - pointer to master state structure */
3513 ipf_fixinisn(fin, is)
3515 ipstate_t *is;
3523 if ((is->is_flags & IS_ISNSYN) != 0) {
3526 ack -= is->is_isninc[0];
3528 ipf_fix_incksum(0, &tcp->th_sum, is->is_sumd[0], 0);
3531 if ((is->is_flags & IS_ISNACK) != 0) {
3534 ack -= is->is_isninc[1];
3536 ipf_fix_incksum(0, &tcp->th_sum, is->is_sumd[1], 0);
3548 /* Walk through all state entries and if an interface pointer match is */
3552 /* If ifp is passed in as being non-null then we are only doing updates for */
3561 ipstate_t *is;
3574 for (is = softs->ipf_state_list; is; is = is->is_next) {
3579 if (ifp == NULL || ifp == is->is_ifp[i])
3580 is->is_ifp[i] = ipf_resolvenic(softc,
3581 is->is_ifname[i],
3582 is->is_v);
3593 /* is(I) - pointer to state structure to delete */
3602 ipf_state_del(softc, is, why)
3604 ipstate_t *is;
3615 if (is->is_phnext != NULL) {
3616 *is->is_phnext = is->is_hnext;
3617 if (is->is_hnext != NULL)
3618 is->is_hnext->is_phnext = is->is_phnext;
3619 if (softs->ipf_state_table[is->is_hv] == NULL)
3621 softs->ipf_state_stats.iss_bucketlen[is->is_hv]--;
3623 is->is_phnext = NULL;
3624 is->is_hnext = NULL;
3629 * Because ipf_state_stats.iss_wild is a count of entries in the state
3633 if (is->is_flags & (SI_WILDP|SI_WILDA)) {
3634 if (!(is->is_flags & SI_CLONED)) {
3637 is->is_flags &= ~(SI_WILDP|SI_WILDA);
3641 * Next, remove it from the timeout queue it is in.
3643 if (is->is_sti.tqe_ifq != NULL)
3644 ipf_deletequeueentry(&is->is_sti);
3647 * If it is still in use by something else, do not go any further,
3648 * but note that at this point it is now an orphan. How can this
3654 MUTEX_ENTER(&is->is_lock);
3655 if (is->is_me != NULL) {
3656 *is->is_me = NULL;
3657 is->is_me = NULL;
3658 is->is_ref--;
3660 is->is_ref--;
3661 if (is->is_ref > 0) {
3664 refs = is->is_ref;
3665 MUTEX_EXIT(&is->is_lock);
3671 fr = is->is_rule;
3672 is->is_rule = NULL;
3676 is->is_family, &is->is_src);
3680 ASSERT(is->is_ref == 0);
3681 MUTEX_EXIT(&is->is_lock);
3683 if (is->is_tqehead[0] != NULL) {
3684 if (ipf_deletetimeoutqueue(is->is_tqehead[0]) == 0)
3685 ipf_freetimeoutqueue(softc, is->is_tqehead[0]);
3687 if (is->is_tqehead[1] != NULL) {
3688 if (ipf_deletetimeoutqueue(is->is_tqehead[1]) == 0)
3689 ipf_freetimeoutqueue(softc, is->is_tqehead[1]);
3692 if (is->is_sync)
3693 ipf_sync_del_state(softc->ipf_sync_soft, is->is_sync);
3698 if (is->is_pnext != NULL) {
3699 *is->is_pnext = is->is_next;
3701 if (is->is_next != NULL)
3702 is->is_next->is_pnext = is->is_pnext;
3704 is->is_pnext = NULL;
3705 is->is_next = NULL;
3709 ipf_state_log(softc, is, why);
3711 if (is->is_p == IPPROTO_TCP)
3723 softs->ipf_state_stats.iss_active_proto[is->is_p]--;
3725 MUTEX_DESTROY(&is->is_lock);
3726 KFREE(is);
3739 /* used here is to keep the queue sorted with the oldest things at the top */
3750 ipstate_t *is;
3760 is = tqe->tqe_parent;
3761 ipf_state_del(softc, is, ISL_EXPIRE);
3771 is = tqe->tqe_parent;
3772 ipf_state_del(softc, is, ISL_EXPIRE);
3822 ipstate_t *is, **isp;
3838 for (isp = &softs->ipf_state_list; ((is = *isp) != NULL); ) {
3839 if ((proto != 0) && (is->is_v != proto)) {
3840 isp = &is->is_next;
3843 if (ipf_state_del(softc, is, ISL_FLUSH) == 0)
3846 isp = &is->is_next;
3861 is = tqe->tqe_parent;
3862 if (is->is_p != IPPROTO_TCP)
3864 if (ipf_state_del(softc, is, ISL_FLUSH) == 0)
3876 is = tqe->tqe_parent;
3877 if (is->is_p != IPPROTO_TCP)
3880 if ((is->is_state[0] > IPF_TCPS_ESTABLISHED) &&
3881 (is->is_state[1] > IPF_TCPS_ESTABLISHED)) {
3882 if (ipf_state_del(softc, is,
3909 is = tqe->tqe_parent;
3910 if (ipf_state_del(softc, is, ISL_FLUSH) == 0)
3926 for (isp = &softs->ipf_state_list; ((is = *isp) != NULL); ) {
3927 if ((proto == 0) || (is->is_v == proto)) {
3928 if (softc->ipf_ticks - is->is_touched > which) {
3929 if (ipf_state_del(softc, is,
3936 isp = &is->is_next;
3948 * Asked to remove inactive entries because the table is full, try
3951 * Another alternative is to implement random drop and drop N entries
3977 /* This function is a stepping stone between ipf_queueflush() and */
3978 /* ipf_state_del(). It is used so we can provide a uniform interface via */
3995 /* tqtab(I) - TCP timeout queue table this is in */
4019 /* A typical procession for a connection is as follows: */
4038 /* Locking: it is assumed that the parent of the tqe structure is locked. */
4091 * does not work when a strict 'flags S keep state' is
4097 * we saw an A, guess 'dir' is in ESTABLISHED
4118 * packets as well; it is yet to be determined how we
4129 * after every packet that is sent. We need to
4139 * we see an A from 'dir' which is in SYN_SENT
4147 * we see an F from 'dir' which is in SYN_SENT
4155 * we see an SA from 'dir' which is already in
4177 * We see an SA from 'dir' which is already in
4183 * we see an F from 'dir' which is in
4284 * if the other side is not active anymore
4299 * already but the other side is still active
4320 * to CLOSED because that is based on the reception
4374 /* is(I) - pointer to state structure */
4382 ipf_state_log(softc, is, type)
4384 struct ipstate *is;
4398 ipsl.isl_pkts[0] = is->is_pkts[0] + is->is_icmppkts[0];
4399 ipsl.isl_bytes[0] = is->is_bytes[0];
4400 ipsl.isl_pkts[1] = is->is_pkts[1] + is->is_icmppkts[1];
4401 ipsl.isl_bytes[1] = is->is_bytes[1];
4402 ipsl.isl_pkts[2] = is->is_pkts[2] + is->is_icmppkts[2];
4403 ipsl.isl_bytes[2] = is->is_bytes[2];
4404 ipsl.isl_pkts[3] = is->is_pkts[3] + is->is_icmppkts[3];
4405 ipsl.isl_bytes[3] = is->is_bytes[3];
4406 ipsl.isl_src = is->is_src;
4407 ipsl.isl_dst = is->is_dst;
4408 ipsl.isl_p = is->is_p;
4409 ipsl.isl_v = is->is_v;
4410 ipsl.isl_flags = is->is_flags;
4411 ipsl.isl_tag = is->is_tag;
4412 ipsl.isl_rulen = is->is_rulen;
4413 (void) strncpy(ipsl.isl_group, is->is_group, FR_GROUPLEN);
4416 ipsl.isl_sport = is->is_sport;
4417 ipsl.isl_dport = is->is_dport;
4419 ipsl.isl_state[0] = is->is_state[0];
4420 ipsl.isl_state[1] = is->is_state[1];
4423 ipsl.isl_itype = is->is_icmp.ici_type;
4425 ipsl.isl_itype = is->is_icmp.ici_type;
4458 ipstate_t *is, **isp;
4501 * but this is the cleanest way. Note further we fill
4505 * watch out here, as ip is in host order and oip6 in network
4555 ((is = *isp) != NULL); ) {
4556 ic = &is->is_icmp;
4557 isp = &is->is_hnext;
4558 if ((is->is_p == pr) &&
4559 !(is->is_pass & FR_NOICMPERR) &&
4562 (is = ipf_matchsrcdst(&ofin, is, &src,
4572 if (!ipf_allowstateicmp(fin, is, &src))
4573 return is;
4620 for (isp = &softs->ipf_state_table[hv]; ((is = *isp) != NULL); ) {
4621 isp = &is->is_hnext;
4629 if ((is->is_p != pr) || (is->is_v != 6) ||
4630 (is->is_pass & FR_NOICMPERR))
4632 is = ipf_matchsrcdst(&ofin, is, &src, &dst, tcp, FI_ICMPCMP);
4633 if ((is != NULL) && (ipf_allowstateicmp(fin, is, &src) == 0))
4634 return is;
4683 /* Do whatever is necessary to "destroy" each of the entries in the array */
4706 /* This function is only called when cleaning up after increasing is_ref by */
4707 /* one earlier in the 'code path' so if is_ref is 1 when entering, we do */
4708 /* have an orphan, otherwise not. However there is a possible race between */
4734 ipstate_t *is = *isp;
4736 is = *isp;
4739 MUTEX_ENTER(&is->is_lock);
4740 if (is->is_ref > 1) {
4741 is->is_ref--;
4742 MUTEX_EXIT(&is->is_lock);
4744 if ((is->is_sti.tqe_state[0] > IPF_TCPS_ESTABLISHED) ||
4745 (is->is_sti.tqe_state[1] > IPF_TCPS_ESTABLISHED)) {
4746 ipf_state_del(softc, is, ISL_EXPIRE);
4751 MUTEX_EXIT(&is->is_lock);
4754 ipf_state_del(softc, is, ISL_ORPHAN);
4763 /* is(I) - pointer to state structure */
4771 ipf_state_setqueue(softc, is, rev)
4773 ipstate_t *is;
4779 if ((is->is_sti.tqe_flags & TQE_RULEBASED) != 0)
4780 nifq = is->is_tqehead[rev];
4785 switch (is->is_p)
4802 nifq = softs->ipf_state_tcptq + is->is_state[rev];
4818 oifq = is->is_sti.tqe_ifq;
4824 ipf_movequeue(softc->ipf_ticks, &is->is_sti, oifq, nifq);
4826 ipf_queueappend(softc->ipf_ticks, &is->is_sti, nifq, is);
4850 ipstate_t *is, *next, zero;
4868 is = token->ipt_data;
4869 if (is == (void *)-1) {
4880 is = token->ipt_data;
4881 if (is == NULL) {
4884 next = is->is_next;
4908 if (is != NULL)
4909 ipf_state_deref(softc, &is);
4923 /* At present the only table it deals with is the hash bucket statistics. */
4957 /* is(I) - pointer to state structure */
4965 ipf_state_setpending(softc, is)
4967 ipstate_t *is;
4972 oifq = is->is_sti.tqe_ifq;
4974 ipf_movequeue(softc->ipf_ticks, &is->is_sti, oifq,
4977 ipf_queueappend(softc->ipf_ticks, &is->is_sti,
4978 &softs->ipf_state_pending, is);
4980 MUTEX_ENTER(&is->is_lock);
4981 if (is->is_me != NULL) {
4982 *is->is_me = NULL;
4983 is->is_me = NULL;
4984 is->is_ref--;
4986 MUTEX_EXIT(&is->is_lock);
5215 * In case there is nothing to do...
5265 ipstate_t **newtab, *is;
5275 * In case there is nothing to do...
5336 for (is = softs->ipf_state_list; is != NULL; is = is->is_next) {
5337 is->is_hnext = NULL;
5338 is->is_phnext = NULL;
5339 hv = is->is_hv % softs->ipf_state_size;
5342 softs->ipf_state_table[hv]->is_phnext = &is->is_hnext;
5345 is->is_phnext = softs->ipf_state_table + hv;
5346 is->is_hnext = softs->ipf_state_table[hv];
5347 softs->ipf_state_table[hv] = is;
5364 /* value being passed in. The timeout queue is added tot the list of those */