1ea761a5dSAlexander V. Chernikov /*- 2ea761a5dSAlexander V. Chernikov * Copyright (c) 2002-2009 Luigi Rizzo, Universita` di Pisa 3ea761a5dSAlexander V. Chernikov * 4ea761a5dSAlexander V. Chernikov * Redistribution and use in source and binary forms, with or without 5ea761a5dSAlexander V. Chernikov * modification, are permitted provided that the following conditions 6ea761a5dSAlexander V. Chernikov * are met: 7ea761a5dSAlexander V. Chernikov * 1. Redistributions of source code must retain the above copyright 8ea761a5dSAlexander V. Chernikov * notice, this list of conditions and the following disclaimer. 9ea761a5dSAlexander V. Chernikov * 2. Redistributions in binary form must reproduce the above copyright 10ea761a5dSAlexander V. Chernikov * notice, this list of conditions and the following disclaimer in the 11ea761a5dSAlexander V. Chernikov * documentation and/or other materials provided with the distribution. 12ea761a5dSAlexander V. Chernikov * 13ea761a5dSAlexander V. Chernikov * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 14ea761a5dSAlexander V. Chernikov * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15ea761a5dSAlexander V. Chernikov * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16ea761a5dSAlexander V. Chernikov * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 17ea761a5dSAlexander V. Chernikov * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18ea761a5dSAlexander V. Chernikov * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19ea761a5dSAlexander V. Chernikov * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20ea761a5dSAlexander V. Chernikov * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21ea761a5dSAlexander V. Chernikov * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22ea761a5dSAlexander V. Chernikov * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23ea761a5dSAlexander V. Chernikov * SUCH DAMAGE. 24ea761a5dSAlexander V. Chernikov */ 25ea761a5dSAlexander V. Chernikov 26ea761a5dSAlexander V. Chernikov #ifndef _IPFW2_TABLE_H 27ea761a5dSAlexander V. Chernikov #define _IPFW2_TABLE_H 28ea761a5dSAlexander V. Chernikov 29ea761a5dSAlexander V. Chernikov /* 30ea761a5dSAlexander V. Chernikov * Internal constants and data structures used by ipfw tables 31d20facb2SAlexander V. Chernikov * not meant to be exported outside the kernel. 32ea761a5dSAlexander V. Chernikov */ 33ea761a5dSAlexander V. Chernikov #ifdef _KERNEL 34ea761a5dSAlexander V. Chernikov 350cba2b28SAlexander V. Chernikov struct table_algo; 360cba2b28SAlexander V. Chernikov struct tables_config { 370cba2b28SAlexander V. Chernikov struct namedobj_instance *namehash; 380cba2b28SAlexander V. Chernikov struct namedobj_instance *valhash; 390cba2b28SAlexander V. Chernikov uint32_t val_size; 400cba2b28SAlexander V. Chernikov uint32_t algo_count; 410cba2b28SAlexander V. Chernikov struct table_algo *algo[256]; 420cba2b28SAlexander V. Chernikov struct table_algo *def_algo[IPFW_TABLE_MAXTYPE + 1]; 430cba2b28SAlexander V. Chernikov TAILQ_HEAD(op_state_l,op_state) state_list; 440cba2b28SAlexander V. Chernikov }; 450cba2b28SAlexander V. Chernikov #define CHAIN_TO_TCFG(chain) ((struct tables_config *)(chain)->tblcfg) 460cba2b28SAlexander V. Chernikov 47ea761a5dSAlexander V. Chernikov struct table_info { 48ea761a5dSAlexander V. Chernikov table_lookup_t *lookup; /* Lookup function */ 49ea761a5dSAlexander V. Chernikov void *state; /* Lookup radix/other structure */ 50ea761a5dSAlexander V. Chernikov void *xstate; /* eXtended state */ 51ea761a5dSAlexander V. Chernikov u_long data; /* Hints for given func */ 52ea761a5dSAlexander V. Chernikov }; 53ea761a5dSAlexander V. Chernikov 540cba2b28SAlexander V. Chernikov struct table_value; 55d3a4f924SAlexander V. Chernikov struct tentry_info { 56d3a4f924SAlexander V. Chernikov void *paddr; 570cba2b28SAlexander V. Chernikov struct table_value *pvalue; 580cba2b28SAlexander V. Chernikov void *ptv; /* Temporary field to hold obj */ 59d3a4f924SAlexander V. Chernikov uint8_t masklen; /* mask length */ 60ac35ff17SAlexander V. Chernikov uint8_t subtype; 61d3a4f924SAlexander V. Chernikov uint16_t flags; /* record flags */ 620cba2b28SAlexander V. Chernikov uint32_t value; /* value index */ 63d3a4f924SAlexander V. Chernikov }; 643a845e10SAlexander V. Chernikov #define TEI_FLAGS_UPDATE 0x0001 /* Add or update rec if exists */ 653a845e10SAlexander V. Chernikov #define TEI_FLAGS_UPDATED 0x0002 /* Entry has been updated */ 663a845e10SAlexander V. Chernikov #define TEI_FLAGS_COMPAT 0x0004 /* Called from old ABI */ 673a845e10SAlexander V. Chernikov #define TEI_FLAGS_DONTADD 0x0008 /* Do not create new rec */ 683a845e10SAlexander V. Chernikov #define TEI_FLAGS_ADDED 0x0010 /* Entry was added */ 693a845e10SAlexander V. Chernikov #define TEI_FLAGS_DELETED 0x0020 /* Entry was deleted */ 703a845e10SAlexander V. Chernikov #define TEI_FLAGS_LIMIT 0x0040 /* Limit was hit */ 713a845e10SAlexander V. Chernikov #define TEI_FLAGS_ERROR 0x0080 /* Unknown request error */ 723a845e10SAlexander V. Chernikov #define TEI_FLAGS_NOTFOUND 0x0100 /* Entry was not found */ 733a845e10SAlexander V. Chernikov #define TEI_FLAGS_EXISTS 0x0200 /* Entry already exists */ 74d3a4f924SAlexander V. Chernikov 7568394ec8SAlexander V. Chernikov typedef int (ta_init)(struct ip_fw_chain *ch, void **ta_state, 76914bffb6SAlexander V. Chernikov struct table_info *ti, char *data, uint8_t tflags); 77ea761a5dSAlexander V. Chernikov typedef void (ta_destroy)(void *ta_state, struct table_info *ti); 7868394ec8SAlexander V. Chernikov typedef int (ta_prepare_add)(struct ip_fw_chain *ch, struct tentry_info *tei, 7968394ec8SAlexander V. Chernikov void *ta_buf); 8068394ec8SAlexander V. Chernikov typedef int (ta_prepare_del)(struct ip_fw_chain *ch, struct tentry_info *tei, 8168394ec8SAlexander V. Chernikov void *ta_buf); 82ea761a5dSAlexander V. Chernikov typedef int (ta_add)(void *ta_state, struct table_info *ti, 83b6ee846eSAlexander V. Chernikov struct tentry_info *tei, void *ta_buf, uint32_t *pnum); 84ea761a5dSAlexander V. Chernikov typedef int (ta_del)(void *ta_state, struct table_info *ti, 85b6ee846eSAlexander V. Chernikov struct tentry_info *tei, void *ta_buf, uint32_t *pnum); 8668394ec8SAlexander V. Chernikov typedef void (ta_flush_entry)(struct ip_fw_chain *ch, struct tentry_info *tei, 8768394ec8SAlexander V. Chernikov void *ta_buf); 88db785d31SAlexander V. Chernikov 89301290bcSAlexander V. Chernikov typedef int (ta_need_modify)(void *ta_state, struct table_info *ti, 90b6ee846eSAlexander V. Chernikov uint32_t count, uint64_t *pflags); 91db785d31SAlexander V. Chernikov typedef int (ta_prepare_mod)(void *ta_buf, uint64_t *pflags); 92db785d31SAlexander V. Chernikov typedef int (ta_fill_mod)(void *ta_state, struct table_info *ti, 93db785d31SAlexander V. Chernikov void *ta_buf, uint64_t *pflags); 94301290bcSAlexander V. Chernikov typedef void (ta_modify)(void *ta_state, struct table_info *ti, 95db785d31SAlexander V. Chernikov void *ta_buf, uint64_t pflags); 96db785d31SAlexander V. Chernikov typedef void (ta_flush_mod)(void *ta_buf); 97db785d31SAlexander V. Chernikov 9868394ec8SAlexander V. Chernikov typedef void (ta_change_ti)(void *ta_state, struct table_info *ti); 99ac35ff17SAlexander V. Chernikov typedef void (ta_print_config)(void *ta_state, struct table_info *ti, char *buf, 100ac35ff17SAlexander V. Chernikov size_t bufsize); 101ea761a5dSAlexander V. Chernikov 102ea761a5dSAlexander V. Chernikov typedef int ta_foreach_f(void *node, void *arg); 103ea761a5dSAlexander V. Chernikov typedef void ta_foreach(void *ta_state, struct table_info *ti, ta_foreach_f *f, 104ea761a5dSAlexander V. Chernikov void *arg); 10581d3153dSAlexander V. Chernikov typedef int ta_dump_tentry(void *ta_state, struct table_info *ti, void *e, 10681d3153dSAlexander V. Chernikov ipfw_obj_tentry *tent); 107914bffb6SAlexander V. Chernikov typedef int ta_find_tentry(void *ta_state, struct table_info *ti, 108914bffb6SAlexander V. Chernikov ipfw_obj_tentry *tent); 1095f379342SAlexander V. Chernikov typedef void ta_dump_tinfo(void *ta_state, struct table_info *ti, 1105f379342SAlexander V. Chernikov ipfw_ta_tinfo *tinfo); 111d3b00c08SAlexander V. Chernikov typedef uint32_t ta_get_count(void *ta_state, struct table_info *ti); 112ea761a5dSAlexander V. Chernikov 113ea761a5dSAlexander V. Chernikov struct table_algo { 1149490a627SAlexander V. Chernikov char name[16]; 11557a1cf95SAlexander V. Chernikov uint32_t idx; 11657a1cf95SAlexander V. Chernikov uint32_t type; 11757a1cf95SAlexander V. Chernikov uint32_t refcnt; 11857a1cf95SAlexander V. Chernikov uint32_t flags; 1190cba2b28SAlexander V. Chernikov uint32_t vlimit; 12057a1cf95SAlexander V. Chernikov size_t ta_buf_size; 121ea761a5dSAlexander V. Chernikov ta_init *init; 122ea761a5dSAlexander V. Chernikov ta_destroy *destroy; 123ea761a5dSAlexander V. Chernikov ta_prepare_add *prepare_add; 124ea761a5dSAlexander V. Chernikov ta_prepare_del *prepare_del; 125ea761a5dSAlexander V. Chernikov ta_add *add; 126ea761a5dSAlexander V. Chernikov ta_del *del; 127ea761a5dSAlexander V. Chernikov ta_flush_entry *flush_entry; 128914bffb6SAlexander V. Chernikov ta_find_tentry *find_tentry; 129301290bcSAlexander V. Chernikov ta_need_modify *need_modify; 130db785d31SAlexander V. Chernikov ta_prepare_mod *prepare_mod; 131db785d31SAlexander V. Chernikov ta_fill_mod *fill_mod; 132db785d31SAlexander V. Chernikov ta_modify *modify; 133db785d31SAlexander V. Chernikov ta_flush_mod *flush_mod; 134914bffb6SAlexander V. Chernikov ta_change_ti *change_ti; 135ea761a5dSAlexander V. Chernikov ta_foreach *foreach; 13681d3153dSAlexander V. Chernikov ta_dump_tentry *dump_tentry; 137ac35ff17SAlexander V. Chernikov ta_print_config *print_config; 138914bffb6SAlexander V. Chernikov ta_dump_tinfo *dump_tinfo; 139d3b00c08SAlexander V. Chernikov ta_get_count *get_count; 140ea761a5dSAlexander V. Chernikov }; 141fd0869d5SAlexander V. Chernikov #define TA_FLAG_DEFAULT 0x01 /* Algo is default for given type */ 142fd0869d5SAlexander V. Chernikov #define TA_FLAG_READONLY 0x02 /* Algo does not support modifications*/ 143d3b00c08SAlexander V. Chernikov #define TA_FLAG_EXTCOUNTER 0x04 /* Algo has external counter available*/ 14468394ec8SAlexander V. Chernikov 1450b565ac0SAlexander V. Chernikov int ipfw_add_table_algo(struct ip_fw_chain *ch, struct table_algo *ta, 1460b565ac0SAlexander V. Chernikov size_t size, int *idx); 1470b565ac0SAlexander V. Chernikov void ipfw_del_table_algo(struct ip_fw_chain *ch, int idx); 148914bffb6SAlexander V. Chernikov 149d3a4f924SAlexander V. Chernikov void ipfw_table_algo_init(struct ip_fw_chain *chain); 150d3a4f924SAlexander V. Chernikov void ipfw_table_algo_destroy(struct ip_fw_chain *chain); 151d3a4f924SAlexander V. Chernikov 152b1d105bcSAlexander V. Chernikov MALLOC_DECLARE(M_IPFW_TBL); 1531832a7b3SAlexander V. Chernikov /* Exported to support legacy opcodes */ 1541832a7b3SAlexander V. Chernikov int add_table_entry(struct ip_fw_chain *ch, struct tid_info *ti, 1553a845e10SAlexander V. Chernikov struct tentry_info *tei, uint8_t flags, uint32_t count); 1561832a7b3SAlexander V. Chernikov int del_table_entry(struct ip_fw_chain *ch, struct tid_info *ti, 1573a845e10SAlexander V. Chernikov struct tentry_info *tei, uint8_t flags, uint32_t count); 1581832a7b3SAlexander V. Chernikov int flush_table(struct ip_fw_chain *ch, struct tid_info *ti); 1590cba2b28SAlexander V. Chernikov 1600cba2b28SAlexander V. Chernikov /* ipfw_table_value.c functions */ 1610cba2b28SAlexander V. Chernikov struct table_config; 1620cba2b28SAlexander V. Chernikov struct tableop_state; 1636b988f3aSAlexander V. Chernikov void ipfw_table_value_init(struct ip_fw_chain *ch, int first); 1646b988f3aSAlexander V. Chernikov void ipfw_table_value_destroy(struct ip_fw_chain *ch, int last); 16557ddf396SAlexander V. Chernikov int ipfw_link_table_values(struct ip_fw_chain *ch, struct tableop_state *ts, 16657ddf396SAlexander V. Chernikov uint8_t flags); 16771af39bfSAlexander V. Chernikov void ipfw_garbage_table_values(struct ip_fw_chain *ch, struct table_config *tc, 1680cba2b28SAlexander V. Chernikov struct tentry_info *tei, uint32_t count, int rollback); 1690cba2b28SAlexander V. Chernikov void ipfw_import_table_value_v1(ipfw_table_value *iv); 1700cba2b28SAlexander V. Chernikov void ipfw_export_table_value_v1(struct table_value *v, ipfw_table_value *iv); 1710cba2b28SAlexander V. Chernikov void ipfw_unref_table_values(struct ip_fw_chain *ch, struct table_config *tc, 1720cba2b28SAlexander V. Chernikov struct table_algo *ta, void *astate, struct table_info *ti); 17371af39bfSAlexander V. Chernikov void rollback_table_values(struct tableop_state *ts); 174ac35ff17SAlexander V. Chernikov 175d3a4f924SAlexander V. Chernikov int ipfw_rewrite_table_uidx(struct ip_fw_chain *chain, 176d3a4f924SAlexander V. Chernikov struct rule_check_info *ci); 177563b5ab1SAlexander V. Chernikov int ipfw_mark_table_kidx(struct ip_fw_chain *chain, struct ip_fw *rule, 178563b5ab1SAlexander V. Chernikov uint32_t *bmask); 179*4a77657cSAndrey V. Elsukov int ipfw_export_table_ntlv(struct ip_fw_chain *ch, uint32_t kidx, 180563b5ab1SAlexander V. Chernikov struct sockopt_data *sd); 181e5eec6ddSAlexander V. Chernikov void ipfw_unref_rule_tables(struct ip_fw_chain *chain, struct ip_fw *rule); 18274b22066SAlexander V. Chernikov struct namedobj_instance *ipfw_get_table_objhash(struct ip_fw_chain *ch); 183d3a4f924SAlexander V. Chernikov 184d3a4f924SAlexander V. Chernikov /* utility functions */ 185a73d728dSAlexander V. Chernikov int ipfw_move_tables_sets(struct ip_fw_chain *ch, ipfw_range_tlv *rt, 186a73d728dSAlexander V. Chernikov uint32_t new_set); 187a73d728dSAlexander V. Chernikov void ipfw_swap_tables_sets(struct ip_fw_chain *ch, uint32_t old_set, 188a73d728dSAlexander V. Chernikov uint32_t new_set, int mv); 189*4a77657cSAndrey V. Elsukov int ipfw_foreach_table_tentry(struct ip_fw_chain *ch, uint32_t kidx, 1904dff4ae0SAlexander V. Chernikov ta_foreach_f f, void *arg); 191d3a4f924SAlexander V. Chernikov 1920cba2b28SAlexander V. Chernikov /* internal functions */ 1930cba2b28SAlexander V. Chernikov void tc_ref(struct table_config *tc); 1940cba2b28SAlexander V. Chernikov void tc_unref(struct table_config *tc); 1950cba2b28SAlexander V. Chernikov 1960cba2b28SAlexander V. Chernikov struct op_state; 1970cba2b28SAlexander V. Chernikov typedef void (op_rollback_f)(void *object, struct op_state *state); 1980cba2b28SAlexander V. Chernikov struct op_state { 1990cba2b28SAlexander V. Chernikov TAILQ_ENTRY(op_state) next; /* chain link */ 2000cba2b28SAlexander V. Chernikov op_rollback_f *func; 2010cba2b28SAlexander V. Chernikov }; 2020cba2b28SAlexander V. Chernikov 2030cba2b28SAlexander V. Chernikov struct tableop_state { 2040cba2b28SAlexander V. Chernikov struct op_state opstate; 2050cba2b28SAlexander V. Chernikov struct ip_fw_chain *ch; 2060cba2b28SAlexander V. Chernikov struct table_config *tc; 2070cba2b28SAlexander V. Chernikov struct table_algo *ta; 2080cba2b28SAlexander V. Chernikov struct tentry_info *tei; 2090cba2b28SAlexander V. Chernikov uint32_t count; 2100cba2b28SAlexander V. Chernikov uint32_t vmask; 2110cba2b28SAlexander V. Chernikov int vshared; 2120cba2b28SAlexander V. Chernikov int modified; 2130cba2b28SAlexander V. Chernikov }; 2140cba2b28SAlexander V. Chernikov 2150cba2b28SAlexander V. Chernikov void add_toperation_state(struct ip_fw_chain *ch, struct tableop_state *ts); 2160cba2b28SAlexander V. Chernikov void del_toperation_state(struct ip_fw_chain *ch, struct tableop_state *ts); 2170cba2b28SAlexander V. Chernikov void rollback_toperation_state(struct ip_fw_chain *ch, void *object); 2180cba2b28SAlexander V. Chernikov 219ea761a5dSAlexander V. Chernikov #endif /* _KERNEL */ 220ea761a5dSAlexander V. Chernikov #endif /* _IPFW2_TABLE_H */ 221