Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v4.11-rc6 140 lines 3.4 kB view raw
1/* Xtables module to match packets using a BPF filter. 2 * Copyright 2013 Google Inc. 3 * Written by Willem de Bruijn <willemb@google.com> 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License version 2 as 7 * published by the Free Software Foundation. 8 */ 9 10#include <linux/module.h> 11#include <linux/skbuff.h> 12#include <linux/filter.h> 13#include <linux/bpf.h> 14 15#include <linux/netfilter/xt_bpf.h> 16#include <linux/netfilter/x_tables.h> 17 18MODULE_AUTHOR("Willem de Bruijn <willemb@google.com>"); 19MODULE_DESCRIPTION("Xtables: BPF filter match"); 20MODULE_LICENSE("GPL"); 21MODULE_ALIAS("ipt_bpf"); 22MODULE_ALIAS("ip6t_bpf"); 23 24static int __bpf_mt_check_bytecode(struct sock_filter *insns, __u16 len, 25 struct bpf_prog **ret) 26{ 27 struct sock_fprog_kern program; 28 29 program.len = len; 30 program.filter = insns; 31 32 if (bpf_prog_create(ret, &program)) { 33 pr_info("bpf: check failed: parse error\n"); 34 return -EINVAL; 35 } 36 37 return 0; 38} 39 40static int __bpf_mt_check_fd(int fd, struct bpf_prog **ret) 41{ 42 struct bpf_prog *prog; 43 44 prog = bpf_prog_get_type(fd, BPF_PROG_TYPE_SOCKET_FILTER); 45 if (IS_ERR(prog)) 46 return PTR_ERR(prog); 47 48 *ret = prog; 49 return 0; 50} 51 52static int bpf_mt_check(const struct xt_mtchk_param *par) 53{ 54 struct xt_bpf_info *info = par->matchinfo; 55 56 return __bpf_mt_check_bytecode(info->bpf_program, 57 info->bpf_program_num_elem, 58 &info->filter); 59} 60 61static int bpf_mt_check_v1(const struct xt_mtchk_param *par) 62{ 63 struct xt_bpf_info_v1 *info = par->matchinfo; 64 65 if (info->mode == XT_BPF_MODE_BYTECODE) 66 return __bpf_mt_check_bytecode(info->bpf_program, 67 info->bpf_program_num_elem, 68 &info->filter); 69 else if (info->mode == XT_BPF_MODE_FD_PINNED || 70 info->mode == XT_BPF_MODE_FD_ELF) 71 return __bpf_mt_check_fd(info->fd, &info->filter); 72 else 73 return -EINVAL; 74} 75 76static bool bpf_mt(const struct sk_buff *skb, struct xt_action_param *par) 77{ 78 const struct xt_bpf_info *info = par->matchinfo; 79 80 return BPF_PROG_RUN(info->filter, skb); 81} 82 83static bool bpf_mt_v1(const struct sk_buff *skb, struct xt_action_param *par) 84{ 85 const struct xt_bpf_info_v1 *info = par->matchinfo; 86 87 return !!bpf_prog_run_save_cb(info->filter, (struct sk_buff *) skb); 88} 89 90static void bpf_mt_destroy(const struct xt_mtdtor_param *par) 91{ 92 const struct xt_bpf_info *info = par->matchinfo; 93 94 bpf_prog_destroy(info->filter); 95} 96 97static void bpf_mt_destroy_v1(const struct xt_mtdtor_param *par) 98{ 99 const struct xt_bpf_info_v1 *info = par->matchinfo; 100 101 bpf_prog_destroy(info->filter); 102} 103 104static struct xt_match bpf_mt_reg[] __read_mostly = { 105 { 106 .name = "bpf", 107 .revision = 0, 108 .family = NFPROTO_UNSPEC, 109 .checkentry = bpf_mt_check, 110 .match = bpf_mt, 111 .destroy = bpf_mt_destroy, 112 .matchsize = sizeof(struct xt_bpf_info), 113 .usersize = offsetof(struct xt_bpf_info, filter), 114 .me = THIS_MODULE, 115 }, 116 { 117 .name = "bpf", 118 .revision = 1, 119 .family = NFPROTO_UNSPEC, 120 .checkentry = bpf_mt_check_v1, 121 .match = bpf_mt_v1, 122 .destroy = bpf_mt_destroy_v1, 123 .matchsize = sizeof(struct xt_bpf_info_v1), 124 .usersize = offsetof(struct xt_bpf_info_v1, filter), 125 .me = THIS_MODULE, 126 }, 127}; 128 129static int __init bpf_mt_init(void) 130{ 131 return xt_register_matches(bpf_mt_reg, ARRAY_SIZE(bpf_mt_reg)); 132} 133 134static void __exit bpf_mt_exit(void) 135{ 136 xt_unregister_matches(bpf_mt_reg, ARRAY_SIZE(bpf_mt_reg)); 137} 138 139module_init(bpf_mt_init); 140module_exit(bpf_mt_exit);