| 1875 | } |
| 1876 | |
| 1877 | static void |
| 1878 | pfsync_update_state(struct pf_state *st) |
| 1879 | { |
| 1880 | struct pfsync_softc *sc = V_pfsyncif; |
| 1881 | bool sync = false, ref = true; |
| 1882 | struct pfsync_bucket *b = pfsync_get_bucket(sc, st); |
| 1883 | |
| 1884 | PF_STATE_LOCK_ASSERT(st); |
| 1885 | PFSYNC_BUCKET_LOCK(b); |
| 1886 | |
| 1887 | if (st->state_flags & PFSTATE_ACK) |
| 1888 | pfsync_undefer_state(st, 0); |
| 1889 | if (st->state_flags & PFSTATE_NOSYNC) { |
| 1890 | if (st->sync_state != PFSYNC_S_NONE) |
| 1891 | pfsync_q_del(st, true, b); |
| 1892 | PFSYNC_BUCKET_UNLOCK(b); |
| 1893 | return; |
| 1894 | } |
| 1895 | |
| 1896 | if (b->b_len == PFSYNC_MINPKT) |
| 1897 | callout_reset(&b->b_tmo, 1 * hz, pfsync_timeout, b); |
| 1898 | |
| 1899 | switch (st->sync_state) { |
| 1900 | case PFSYNC_S_UPD_C: |
| 1901 | case PFSYNC_S_UPD: |
| 1902 | case PFSYNC_S_INS: |
| 1903 | /* we're already handling it */ |
| 1904 | |
| 1905 | if (st->key[PF_SK_WIRE]->proto == IPPROTO_TCP) { |
| 1906 | st->sync_updates++; |
| 1907 | if (st->sync_updates >= sc->sc_maxupdates) |
| 1908 | sync = true; |
| 1909 | } |
| 1910 | break; |
| 1911 | |
| 1912 | case PFSYNC_S_IACK: |
| 1913 | pfsync_q_del(st, false, b); |
| 1914 | ref = false; |
| 1915 | /* FALLTHROUGH */ |
| 1916 | |
| 1917 | case PFSYNC_S_NONE: |
| 1918 | pfsync_q_ins(st, PFSYNC_S_UPD_C, ref); |
| 1919 | st->sync_updates = 0; |
| 1920 | break; |
| 1921 | |
| 1922 | default: |
| 1923 | panic("%s: unexpected sync state %d", __func__, st->sync_state); |
| 1924 | } |
| 1925 | |
| 1926 | if (sync || (time_uptime - st->pfsync_time) < 2) |
| 1927 | pfsync_push(b); |
| 1928 | |
| 1929 | PFSYNC_BUCKET_UNLOCK(b); |
| 1930 | } |
| 1931 | |
| 1932 | static void |
| 1933 | pfsync_request_update(u_int32_t creatorid, u_int64_t id) |
no test coverage detected