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

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

Version: ~ [ linux-5.2 ] ~ [ linux-5.1.16 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.57 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.132 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.184 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.184 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.69 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-3.9.11 ] ~ [ linux-3.8.13 ] ~ [ linux-3.7.10 ] ~ [ linux-3.6.11 ] ~ [ linux-3.5.7 ] ~ [ linux-3.4.113 ] ~ [ linux-3.3.8 ] ~ [ linux-3.2.102 ] ~ [ linux-3.1.10 ] ~ [ linux-3.0.101 ] ~ [ linux-2.6.39.4 ] ~ [ linux-2.6.38.8 ] ~ [ linux-2.6.37.6 ] ~ [ linux-2.6.36.4 ] ~ [ linux-2.6.35.14 ] ~ [ linux-2.6.34.15 ] ~ [ linux-2.6.33.20 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /*
  2  * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
  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  * Development of this code funded by Astaro AG (http://www.astaro.com/)
  9  */
 10 
 11 #include <asm/unaligned.h>
 12 #include <linux/kernel.h>
 13 #include <linux/init.h>
 14 #include <linux/module.h>
 15 #include <linux/netlink.h>
 16 #include <linux/netfilter.h>
 17 #include <linux/netfilter/nf_tables.h>
 18 #include <net/netfilter/nf_tables_core.h>
 19 #include <net/netfilter/nf_tables.h>
 20 
 21 struct nft_byteorder {
 22         enum nft_registers      sreg:8;
 23         enum nft_registers      dreg:8;
 24         enum nft_byteorder_ops  op:8;
 25         u8                      len;
 26         u8                      size;
 27 };
 28 
 29 static void nft_byteorder_eval(const struct nft_expr *expr,
 30                                struct nft_regs *regs,
 31                                const struct nft_pktinfo *pkt)
 32 {
 33         const struct nft_byteorder *priv = nft_expr_priv(expr);
 34         u32 *src = &regs->data[priv->sreg];
 35         u32 *dst = &regs->data[priv->dreg];
 36         union { u32 u32; u16 u16; } *s, *d;
 37         unsigned int i;
 38 
 39         s = (void *)src;
 40         d = (void *)dst;
 41 
 42         switch (priv->size) {
 43         case 8: {
 44                 u64 src64;
 45 
 46                 switch (priv->op) {
 47                 case NFT_BYTEORDER_NTOH:
 48                         for (i = 0; i < priv->len / 8; i++) {
 49                                 src64 = get_unaligned((u64 *)&src[i]);
 50                                 put_unaligned_be64(src64, &dst[i]);
 51                         }
 52                         break;
 53                 case NFT_BYTEORDER_HTON:
 54                         for (i = 0; i < priv->len / 8; i++) {
 55                                 src64 = get_unaligned_be64(&src[i]);
 56                                 put_unaligned(src64, (u64 *)&dst[i]);
 57                         }
 58                         break;
 59                 }
 60                 break;
 61         }
 62         case 4:
 63                 switch (priv->op) {
 64                 case NFT_BYTEORDER_NTOH:
 65                         for (i = 0; i < priv->len / 4; i++)
 66                                 d[i].u32 = ntohl((__force __be32)s[i].u32);
 67                         break;
 68                 case NFT_BYTEORDER_HTON:
 69                         for (i = 0; i < priv->len / 4; i++)
 70                                 d[i].u32 = (__force __u32)htonl(s[i].u32);
 71                         break;
 72                 }
 73                 break;
 74         case 2:
 75                 switch (priv->op) {
 76                 case NFT_BYTEORDER_NTOH:
 77                         for (i = 0; i < priv->len / 2; i++)
 78                                 d[i].u16 = ntohs((__force __be16)s[i].u16);
 79                         break;
 80                 case NFT_BYTEORDER_HTON:
 81                         for (i = 0; i < priv->len / 2; i++)
 82                                 d[i].u16 = (__force __u16)htons(s[i].u16);
 83                         break;
 84                 }
 85                 break;
 86         }
 87 }
 88 
 89 static const struct nla_policy nft_byteorder_policy[NFTA_BYTEORDER_MAX + 1] = {
 90         [NFTA_BYTEORDER_SREG]   = { .type = NLA_U32 },
 91         [NFTA_BYTEORDER_DREG]   = { .type = NLA_U32 },
 92         [NFTA_BYTEORDER_OP]     = { .type = NLA_U32 },
 93         [NFTA_BYTEORDER_LEN]    = { .type = NLA_U32 },
 94         [NFTA_BYTEORDER_SIZE]   = { .type = NLA_U32 },
 95 };
 96 
 97 static int nft_byteorder_init(const struct nft_ctx *ctx,
 98                               const struct nft_expr *expr,
 99                               const struct nlattr * const tb[])
100 {
101         struct nft_byteorder *priv = nft_expr_priv(expr);
102         int err;
103 
104         if (tb[NFTA_BYTEORDER_SREG] == NULL ||
105             tb[NFTA_BYTEORDER_DREG] == NULL ||
106             tb[NFTA_BYTEORDER_LEN] == NULL ||
107             tb[NFTA_BYTEORDER_SIZE] == NULL ||
108             tb[NFTA_BYTEORDER_OP] == NULL)
109                 return -EINVAL;
110 
111         priv->op = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_OP]));
112         switch (priv->op) {
113         case NFT_BYTEORDER_NTOH:
114         case NFT_BYTEORDER_HTON:
115                 break;
116         default:
117                 return -EINVAL;
118         }
119 
120         priv->size = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_SIZE]));
121         switch (priv->size) {
122         case 2:
123         case 4:
124         case 8:
125                 break;
126         default:
127                 return -EINVAL;
128         }
129 
130         priv->sreg = nft_parse_register(tb[NFTA_BYTEORDER_SREG]);
131         priv->len  = ntohl(nla_get_be32(tb[NFTA_BYTEORDER_LEN]));
132         err = nft_validate_register_load(priv->sreg, priv->len);
133         if (err < 0)
134                 return err;
135 
136         priv->dreg = nft_parse_register(tb[NFTA_BYTEORDER_DREG]);
137         return nft_validate_register_store(ctx, priv->dreg, NULL,
138                                            NFT_DATA_VALUE, priv->len);
139 }
140 
141 static int nft_byteorder_dump(struct sk_buff *skb, const struct nft_expr *expr)
142 {
143         const struct nft_byteorder *priv = nft_expr_priv(expr);
144 
145         if (nft_dump_register(skb, NFTA_BYTEORDER_SREG, priv->sreg))
146                 goto nla_put_failure;
147         if (nft_dump_register(skb, NFTA_BYTEORDER_DREG, priv->dreg))
148                 goto nla_put_failure;
149         if (nla_put_be32(skb, NFTA_BYTEORDER_OP, htonl(priv->op)))
150                 goto nla_put_failure;
151         if (nla_put_be32(skb, NFTA_BYTEORDER_LEN, htonl(priv->len)))
152                 goto nla_put_failure;
153         if (nla_put_be32(skb, NFTA_BYTEORDER_SIZE, htonl(priv->size)))
154                 goto nla_put_failure;
155         return 0;
156 
157 nla_put_failure:
158         return -1;
159 }
160 
161 static struct nft_expr_type nft_byteorder_type;
162 static const struct nft_expr_ops nft_byteorder_ops = {
163         .type           = &nft_byteorder_type,
164         .size           = NFT_EXPR_SIZE(sizeof(struct nft_byteorder)),
165         .eval           = nft_byteorder_eval,
166         .init           = nft_byteorder_init,
167         .dump           = nft_byteorder_dump,
168 };
169 
170 static struct nft_expr_type nft_byteorder_type __read_mostly = {
171         .name           = "byteorder",
172         .ops            = &nft_byteorder_ops,
173         .policy         = nft_byteorder_policy,
174         .maxattr        = NFTA_BYTEORDER_MAX,
175         .owner          = THIS_MODULE,
176 };
177 
178 int __init nft_byteorder_module_init(void)
179 {
180         return nft_register_expr(&nft_byteorder_type);
181 }
182 
183 void nft_byteorder_module_exit(void)
184 {
185         nft_unregister_expr(&nft_byteorder_type);
186 }
187 

~ [ 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