~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/netfilter/nft_rt.c

Version: ~ [ linux-6.4-rc3 ] ~ [ linux-6.3.4 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.30 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.113 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.180 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.243 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.283 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.315 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (c) 2016 Anders K. Pedersen <akp@cohaesio.com>
  3  *
  4  * This program is free software; you can redistribute it and/or modify
  5  * it under the terms of the GNU General Public License version 2 as
  6  * published by the Free Software Foundation.
  7  */
  8 
  9 #include <linux/kernel.h>
 10 #include <linux/init.h>
 11 #include <linux/module.h>
 12 #include <linux/netlink.h>
 13 #include <linux/netfilter.h>
 14 #include <linux/netfilter/nf_tables.h>
 15 #include <net/dst.h>
 16 #include <net/ip6_route.h>
 17 #include <net/route.h>
 18 #include <net/netfilter/nf_tables.h>
 19 #include <net/netfilter/nf_tables_core.h>
 20 
 21 struct nft_rt {
 22         enum nft_rt_keys        key:8;
 23         enum nft_registers      dreg:8;
 24 };
 25 
 26 static void nft_rt_get_eval(const struct nft_expr *expr,
 27                             struct nft_regs *regs,
 28                             const struct nft_pktinfo *pkt)
 29 {
 30         const struct nft_rt *priv = nft_expr_priv(expr);
 31         const struct sk_buff *skb = pkt->skb;
 32         u32 *dest = &regs->data[priv->dreg];
 33         const struct dst_entry *dst;
 34 
 35         dst = skb_dst(skb);
 36         if (!dst)
 37                 goto err;
 38 
 39         switch (priv->key) {
 40 #ifdef CONFIG_IP_ROUTE_CLASSID
 41         case NFT_RT_CLASSID:
 42                 *dest = dst->tclassid;
 43                 break;
 44 #endif
 45         case NFT_RT_NEXTHOP4:
 46                 if (nft_pf(pkt) != NFPROTO_IPV4)
 47                         goto err;
 48 
 49                 *dest = rt_nexthop((const struct rtable *)dst,
 50                                    ip_hdr(skb)->daddr);
 51                 break;
 52         case NFT_RT_NEXTHOP6:
 53                 if (nft_pf(pkt) != NFPROTO_IPV6)
 54                         goto err;
 55 
 56                 memcpy(dest, rt6_nexthop((struct rt6_info *)dst,
 57                                          &ipv6_hdr(skb)->daddr),
 58                        sizeof(struct in6_addr));
 59                 break;
 60         default:
 61                 WARN_ON(1);
 62                 goto err;
 63         }
 64         return;
 65 
 66 err:
 67         regs->verdict.code = NFT_BREAK;
 68 }
 69 
 70 const struct nla_policy nft_rt_policy[NFTA_RT_MAX + 1] = {
 71         [NFTA_RT_DREG]          = { .type = NLA_U32 },
 72         [NFTA_RT_KEY]           = { .type = NLA_U32 },
 73 };
 74 
 75 static int nft_rt_get_init(const struct nft_ctx *ctx,
 76                            const struct nft_expr *expr,
 77                            const struct nlattr * const tb[])
 78 {
 79         struct nft_rt *priv = nft_expr_priv(expr);
 80         unsigned int len;
 81 
 82         if (tb[NFTA_RT_KEY] == NULL ||
 83             tb[NFTA_RT_DREG] == NULL)
 84                 return -EINVAL;
 85 
 86         priv->key = ntohl(nla_get_be32(tb[NFTA_RT_KEY]));
 87         switch (priv->key) {
 88 #ifdef CONFIG_IP_ROUTE_CLASSID
 89         case NFT_RT_CLASSID:
 90 #endif
 91         case NFT_RT_NEXTHOP4:
 92                 len = sizeof(u32);
 93                 break;
 94         case NFT_RT_NEXTHOP6:
 95                 len = sizeof(struct in6_addr);
 96                 break;
 97         default:
 98                 return -EOPNOTSUPP;
 99         }
100 
101         priv->dreg = nft_parse_register(tb[NFTA_RT_DREG]);
102         return nft_validate_register_store(ctx, priv->dreg, NULL,
103                                            NFT_DATA_VALUE, len);
104 }
105 
106 static int nft_rt_get_dump(struct sk_buff *skb,
107                            const struct nft_expr *expr)
108 {
109         const struct nft_rt *priv = nft_expr_priv(expr);
110 
111         if (nla_put_be32(skb, NFTA_RT_KEY, htonl(priv->key)))
112                 goto nla_put_failure;
113         if (nft_dump_register(skb, NFTA_RT_DREG, priv->dreg))
114                 goto nla_put_failure;
115         return 0;
116 
117 nla_put_failure:
118         return -1;
119 }
120 
121 static struct nft_expr_type nft_rt_type;
122 static const struct nft_expr_ops nft_rt_get_ops = {
123         .type           = &nft_rt_type,
124         .size           = NFT_EXPR_SIZE(sizeof(struct nft_rt)),
125         .eval           = nft_rt_get_eval,
126         .init           = nft_rt_get_init,
127         .dump           = nft_rt_get_dump,
128 };
129 
130 static struct nft_expr_type nft_rt_type __read_mostly = {
131         .name           = "rt",
132         .ops            = &nft_rt_get_ops,
133         .policy         = nft_rt_policy,
134         .maxattr        = NFTA_RT_MAX,
135         .owner          = THIS_MODULE,
136 };
137 
138 static int __init nft_rt_module_init(void)
139 {
140         return nft_register_expr(&nft_rt_type);
141 }
142 
143 static void __exit nft_rt_module_exit(void)
144 {
145         nft_unregister_expr(&nft_rt_type);
146 }
147 
148 module_init(nft_rt_module_init);
149 module_exit(nft_rt_module_exit);
150 
151 MODULE_LICENSE("GPL");
152 MODULE_AUTHOR("Anders K. Pedersen <akp@cohaesio.com>");
153 MODULE_ALIAS_NFT_EXPR("rt");
154 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp