Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * Copyright (c) 2017 Pablo M. Bermudo Garay <pablombg@gmail.com>
0004  *
0005  * This code is based on net/netfilter/nft_fib_inet.c, written by
0006  * Florian Westphal <fw@strlen.de>.
0007  */
0008 
0009 #include <linux/kernel.h>
0010 #include <linux/init.h>
0011 #include <linux/module.h>
0012 #include <linux/netlink.h>
0013 #include <linux/netfilter.h>
0014 #include <linux/netfilter/nf_tables.h>
0015 #include <net/netfilter/nf_tables_core.h>
0016 #include <net/netfilter/nf_tables.h>
0017 #include <net/ipv6.h>
0018 
0019 #include <net/netfilter/nft_fib.h>
0020 
0021 static void nft_fib_netdev_eval(const struct nft_expr *expr,
0022                 struct nft_regs *regs,
0023                 const struct nft_pktinfo *pkt)
0024 {
0025     const struct nft_fib *priv = nft_expr_priv(expr);
0026 
0027     switch (ntohs(pkt->skb->protocol)) {
0028     case ETH_P_IP:
0029         switch (priv->result) {
0030         case NFT_FIB_RESULT_OIF:
0031         case NFT_FIB_RESULT_OIFNAME:
0032             return nft_fib4_eval(expr, regs, pkt);
0033         case NFT_FIB_RESULT_ADDRTYPE:
0034             return nft_fib4_eval_type(expr, regs, pkt);
0035         }
0036         break;
0037     case ETH_P_IPV6:
0038         if (!ipv6_mod_enabled())
0039             break;
0040         switch (priv->result) {
0041         case NFT_FIB_RESULT_OIF:
0042         case NFT_FIB_RESULT_OIFNAME:
0043             return nft_fib6_eval(expr, regs, pkt);
0044         case NFT_FIB_RESULT_ADDRTYPE:
0045             return nft_fib6_eval_type(expr, regs, pkt);
0046         }
0047         break;
0048     }
0049 
0050     regs->verdict.code = NFT_BREAK;
0051 }
0052 
0053 static struct nft_expr_type nft_fib_netdev_type;
0054 static const struct nft_expr_ops nft_fib_netdev_ops = {
0055     .type       = &nft_fib_netdev_type,
0056     .size       = NFT_EXPR_SIZE(sizeof(struct nft_fib)),
0057     .eval       = nft_fib_netdev_eval,
0058     .init       = nft_fib_init,
0059     .dump       = nft_fib_dump,
0060     .validate   = nft_fib_validate,
0061     .reduce     = nft_fib_reduce,
0062 };
0063 
0064 static struct nft_expr_type nft_fib_netdev_type __read_mostly = {
0065     .family     = NFPROTO_NETDEV,
0066     .name       = "fib",
0067     .ops        = &nft_fib_netdev_ops,
0068     .policy     = nft_fib_policy,
0069     .maxattr    = NFTA_FIB_MAX,
0070     .owner      = THIS_MODULE,
0071 };
0072 
0073 static int __init nft_fib_netdev_module_init(void)
0074 {
0075     return nft_register_expr(&nft_fib_netdev_type);
0076 }
0077 
0078 static void __exit nft_fib_netdev_module_exit(void)
0079 {
0080     nft_unregister_expr(&nft_fib_netdev_type);
0081 }
0082 
0083 module_init(nft_fib_netdev_module_init);
0084 module_exit(nft_fib_netdev_module_exit);
0085 
0086 MODULE_LICENSE("GPL");
0087 MODULE_AUTHOR("Pablo M. Bermudo Garay <pablombg@gmail.com>");
0088 MODULE_ALIAS_NFT_AF_EXPR(5, "fib");
0089 MODULE_DESCRIPTION("nftables netdev fib lookups support");