1166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal#include <stdio.h> 2166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal#include <xtables.h> 3166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal#include <linux/netfilter/xt_rpfilter.h> 4166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 5166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalenum { 6166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal O_RPF_LOOSE = 0, 7166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal O_RPF_VMARK = 1, 8166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal O_RPF_ACCEPT_LOCAL = 2, 9166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal O_RPF_INVERT = 3, 10166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal}; 11166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 12166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalstatic void rpfilter_help(void) 13166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal{ 14166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal printf( 15166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal"rpfilter match options:\n" 16166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal" --loose permit reverse path via any interface\n" 17166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal" --validmark use skb nfmark when performing route lookup\n" 18166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal" --accept-local do not reject packets with a local source address\n" 19166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal" --invert match packets that failed the reverse path test\n" 20166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal ); 21166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal} 22166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 23166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalstatic const struct xt_option_entry rpfilter_opts[] = { 24166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal {.name = "loose", .id = O_RPF_LOOSE, .type = XTTYPE_NONE, }, 25166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal {.name = "validmark", .id = O_RPF_VMARK, .type = XTTYPE_NONE, }, 26166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal {.name = "accept-local", .id = O_RPF_ACCEPT_LOCAL, .type = XTTYPE_NONE, }, 27166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal {.name = "invert", .id = O_RPF_INVERT, .type = XTTYPE_NONE, }, 28166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal XTOPT_TABLEEND, 29166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal}; 30166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 31166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalstatic void rpfilter_parse(struct xt_option_call *cb) 32166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal{ 33166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal struct xt_rpfilter_info *rpfinfo = cb->data; 34166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 35166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal xtables_option_parse(cb); 36166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal switch (cb->entry->id) { 37166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal case O_RPF_LOOSE: 38166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal rpfinfo->flags |= XT_RPFILTER_LOOSE; 39166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal break; 40166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal case O_RPF_VMARK: 41166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal rpfinfo->flags |= XT_RPFILTER_VALID_MARK; 42166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal break; 43166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal case O_RPF_ACCEPT_LOCAL: 44166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal rpfinfo->flags |= XT_RPFILTER_ACCEPT_LOCAL; 45166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal break; 46166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal case O_RPF_INVERT: 47166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal rpfinfo->flags |= XT_RPFILTER_INVERT; 48166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal break; 49166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal } 50166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal} 51166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 52166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalstatic void 53166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalrpfilter_print_prefix(const void *ip, const void *matchinfo, 54166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal const char *prefix) 55166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal{ 56166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal const struct xt_rpfilter_info *info = matchinfo; 57166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal if (info->flags & XT_RPFILTER_LOOSE) 58166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal printf(" %s%s", prefix, rpfilter_opts[O_RPF_LOOSE].name); 59166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal if (info->flags & XT_RPFILTER_VALID_MARK) 60166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal printf(" %s%s", prefix, rpfilter_opts[O_RPF_VMARK].name); 61166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal if (info->flags & XT_RPFILTER_ACCEPT_LOCAL) 62166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal printf(" %s%s", prefix, rpfilter_opts[O_RPF_ACCEPT_LOCAL].name); 63166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal if (info->flags & XT_RPFILTER_INVERT) 64166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal printf(" %s%s", prefix, rpfilter_opts[O_RPF_INVERT].name); 65166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal} 66166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 67166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 68166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalstatic void 69166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalrpfilter_print(const void *ip, const struct xt_entry_match *match, int numeric) 70166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal{ 71166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal printf(" rpfilter"); 72166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal return rpfilter_print_prefix(ip, match->data, ""); 73166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal} 74166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 75166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalstatic void rpfilter_save(const void *ip, const struct xt_entry_match *match) 76166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal{ 77166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal return rpfilter_print_prefix(ip, match->data, "--"); 78166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal} 79166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 80166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalstatic struct xtables_match rpfilter_match = { 81166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .family = NFPROTO_UNSPEC, 82166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .name = "rpfilter", 83166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .version = XTABLES_VERSION, 84166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .size = XT_ALIGN(sizeof(struct xt_rpfilter_info)), 85166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .userspacesize = XT_ALIGN(sizeof(struct xt_rpfilter_info)), 86166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .help = rpfilter_help, 87166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .print = rpfilter_print, 88166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .save = rpfilter_save, 89166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .x6_parse = rpfilter_parse, 90166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal .x6_options = rpfilter_opts, 91166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal}; 92166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal 93166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphalvoid _init(void) 94166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal{ 95166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal xtables_register_match(&rpfilter_match); 96166b92d3fb2a7fc008df1b59332ef528a9a573eaFlorian Westphal} 97