]> asedeno.scripts.mit.edu Git - linux.git/blob - net/netfilter/nft_meta.c
Merge mlx5-next into rdma for-next
[linux.git] / net / netfilter / nft_meta.c
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
4  * Copyright (c) 2014 Intel Corporation
5  * Author: Tomasz Bursztyka <tomasz.bursztyka@linux.intel.com>
6  *
7  * Development of this code funded by Astaro AG (http://www.astaro.com/)
8  */
9
10 #include <linux/kernel.h>
11 #include <linux/netlink.h>
12 #include <linux/netfilter.h>
13 #include <linux/netfilter/nf_tables.h>
14 #include <linux/in.h>
15 #include <linux/ip.h>
16 #include <linux/ipv6.h>
17 #include <linux/smp.h>
18 #include <linux/static_key.h>
19 #include <net/dst.h>
20 #include <net/sock.h>
21 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
22 #include <net/netfilter/nf_tables.h>
23 #include <net/netfilter/nf_tables_core.h>
24
25 #include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
26
27 struct nft_meta {
28         enum nft_meta_keys      key:8;
29         union {
30                 enum nft_registers      dreg:8;
31                 enum nft_registers      sreg:8;
32         };
33 };
34
35 static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
36
37 #ifdef CONFIG_NF_TABLES_BRIDGE
38 #include "../bridge/br_private.h"
39 #endif
40
41 void nft_meta_get_eval(const struct nft_expr *expr,
42                        struct nft_regs *regs,
43                        const struct nft_pktinfo *pkt)
44 {
45         const struct nft_meta *priv = nft_expr_priv(expr);
46         const struct sk_buff *skb = pkt->skb;
47         const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
48         struct sock *sk;
49         u32 *dest = &regs->data[priv->dreg];
50 #ifdef CONFIG_NF_TABLES_BRIDGE
51         const struct net_bridge_port *p;
52 #endif
53
54         switch (priv->key) {
55         case NFT_META_LEN:
56                 *dest = skb->len;
57                 break;
58         case NFT_META_PROTOCOL:
59                 nft_reg_store16(dest, (__force u16)skb->protocol);
60                 break;
61         case NFT_META_NFPROTO:
62                 nft_reg_store8(dest, nft_pf(pkt));
63                 break;
64         case NFT_META_L4PROTO:
65                 if (!pkt->tprot_set)
66                         goto err;
67                 nft_reg_store8(dest, pkt->tprot);
68                 break;
69         case NFT_META_PRIORITY:
70                 *dest = skb->priority;
71                 break;
72         case NFT_META_MARK:
73                 *dest = skb->mark;
74                 break;
75         case NFT_META_IIF:
76                 if (in == NULL)
77                         goto err;
78                 *dest = in->ifindex;
79                 break;
80         case NFT_META_OIF:
81                 if (out == NULL)
82                         goto err;
83                 *dest = out->ifindex;
84                 break;
85         case NFT_META_IIFNAME:
86                 if (in == NULL)
87                         goto err;
88                 strncpy((char *)dest, in->name, IFNAMSIZ);
89                 break;
90         case NFT_META_OIFNAME:
91                 if (out == NULL)
92                         goto err;
93                 strncpy((char *)dest, out->name, IFNAMSIZ);
94                 break;
95         case NFT_META_IIFTYPE:
96                 if (in == NULL)
97                         goto err;
98                 nft_reg_store16(dest, in->type);
99                 break;
100         case NFT_META_OIFTYPE:
101                 if (out == NULL)
102                         goto err;
103                 nft_reg_store16(dest, out->type);
104                 break;
105         case NFT_META_SKUID:
106                 sk = skb_to_full_sk(skb);
107                 if (!sk || !sk_fullsock(sk) ||
108                     !net_eq(nft_net(pkt), sock_net(sk)))
109                         goto err;
110
111                 read_lock_bh(&sk->sk_callback_lock);
112                 if (sk->sk_socket == NULL ||
113                     sk->sk_socket->file == NULL) {
114                         read_unlock_bh(&sk->sk_callback_lock);
115                         goto err;
116                 }
117
118                 *dest = from_kuid_munged(&init_user_ns,
119                                 sk->sk_socket->file->f_cred->fsuid);
120                 read_unlock_bh(&sk->sk_callback_lock);
121                 break;
122         case NFT_META_SKGID:
123                 sk = skb_to_full_sk(skb);
124                 if (!sk || !sk_fullsock(sk) ||
125                     !net_eq(nft_net(pkt), sock_net(sk)))
126                         goto err;
127
128                 read_lock_bh(&sk->sk_callback_lock);
129                 if (sk->sk_socket == NULL ||
130                     sk->sk_socket->file == NULL) {
131                         read_unlock_bh(&sk->sk_callback_lock);
132                         goto err;
133                 }
134                 *dest = from_kgid_munged(&init_user_ns,
135                                  sk->sk_socket->file->f_cred->fsgid);
136                 read_unlock_bh(&sk->sk_callback_lock);
137                 break;
138 #ifdef CONFIG_IP_ROUTE_CLASSID
139         case NFT_META_RTCLASSID: {
140                 const struct dst_entry *dst = skb_dst(skb);
141
142                 if (dst == NULL)
143                         goto err;
144                 *dest = dst->tclassid;
145                 break;
146         }
147 #endif
148 #ifdef CONFIG_NETWORK_SECMARK
149         case NFT_META_SECMARK:
150                 *dest = skb->secmark;
151                 break;
152 #endif
153         case NFT_META_PKTTYPE:
154                 if (skb->pkt_type != PACKET_LOOPBACK) {
155                         nft_reg_store8(dest, skb->pkt_type);
156                         break;
157                 }
158
159                 switch (nft_pf(pkt)) {
160                 case NFPROTO_IPV4:
161                         if (ipv4_is_multicast(ip_hdr(skb)->daddr))
162                                 nft_reg_store8(dest, PACKET_MULTICAST);
163                         else
164                                 nft_reg_store8(dest, PACKET_BROADCAST);
165                         break;
166                 case NFPROTO_IPV6:
167                         nft_reg_store8(dest, PACKET_MULTICAST);
168                         break;
169                 case NFPROTO_NETDEV:
170                         switch (skb->protocol) {
171                         case htons(ETH_P_IP): {
172                                 int noff = skb_network_offset(skb);
173                                 struct iphdr *iph, _iph;
174
175                                 iph = skb_header_pointer(skb, noff,
176                                                          sizeof(_iph), &_iph);
177                                 if (!iph)
178                                         goto err;
179
180                                 if (ipv4_is_multicast(iph->daddr))
181                                         nft_reg_store8(dest, PACKET_MULTICAST);
182                                 else
183                                         nft_reg_store8(dest, PACKET_BROADCAST);
184
185                                 break;
186                         }
187                         case htons(ETH_P_IPV6):
188                                 nft_reg_store8(dest, PACKET_MULTICAST);
189                                 break;
190                         default:
191                                 WARN_ON_ONCE(1);
192                                 goto err;
193                         }
194                         break;
195                 default:
196                         WARN_ON_ONCE(1);
197                         goto err;
198                 }
199                 break;
200         case NFT_META_CPU:
201                 *dest = raw_smp_processor_id();
202                 break;
203         case NFT_META_IIFGROUP:
204                 if (in == NULL)
205                         goto err;
206                 *dest = in->group;
207                 break;
208         case NFT_META_OIFGROUP:
209                 if (out == NULL)
210                         goto err;
211                 *dest = out->group;
212                 break;
213 #ifdef CONFIG_CGROUP_NET_CLASSID
214         case NFT_META_CGROUP:
215                 sk = skb_to_full_sk(skb);
216                 if (!sk || !sk_fullsock(sk) ||
217                     !net_eq(nft_net(pkt), sock_net(sk)))
218                         goto err;
219                 *dest = sock_cgroup_classid(&sk->sk_cgrp_data);
220                 break;
221 #endif
222         case NFT_META_PRANDOM: {
223                 struct rnd_state *state = this_cpu_ptr(&nft_prandom_state);
224                 *dest = prandom_u32_state(state);
225                 break;
226         }
227 #ifdef CONFIG_XFRM
228         case NFT_META_SECPATH:
229                 nft_reg_store8(dest, secpath_exists(skb));
230                 break;
231 #endif
232 #ifdef CONFIG_NF_TABLES_BRIDGE
233         case NFT_META_BRI_IIFNAME:
234                 if (in == NULL || (p = br_port_get_rcu(in)) == NULL)
235                         goto err;
236                 strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
237                 return;
238         case NFT_META_BRI_OIFNAME:
239                 if (out == NULL || (p = br_port_get_rcu(out)) == NULL)
240                         goto err;
241                 strncpy((char *)dest, p->br->dev->name, IFNAMSIZ);
242                 return;
243 #endif
244         case NFT_META_IIFKIND:
245                 if (in == NULL || in->rtnl_link_ops == NULL)
246                         goto err;
247                 strncpy((char *)dest, in->rtnl_link_ops->kind, IFNAMSIZ);
248                 break;
249         case NFT_META_OIFKIND:
250                 if (out == NULL || out->rtnl_link_ops == NULL)
251                         goto err;
252                 strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
253                 break;
254         default:
255                 WARN_ON(1);
256                 goto err;
257         }
258         return;
259
260 err:
261         regs->verdict.code = NFT_BREAK;
262 }
263
264 static void nft_meta_set_eval(const struct nft_expr *expr,
265                               struct nft_regs *regs,
266                                const struct nft_pktinfo *pkt)
267 {
268         const struct nft_meta *meta = nft_expr_priv(expr);
269         struct sk_buff *skb = pkt->skb;
270         u32 *sreg = &regs->data[meta->sreg];
271         u32 value = *sreg;
272         u8 value8;
273
274         switch (meta->key) {
275         case NFT_META_MARK:
276                 skb->mark = value;
277                 break;
278         case NFT_META_PRIORITY:
279                 skb->priority = value;
280                 break;
281         case NFT_META_PKTTYPE:
282                 value8 = nft_reg_load8(sreg);
283
284                 if (skb->pkt_type != value8 &&
285                     skb_pkt_type_ok(value8) &&
286                     skb_pkt_type_ok(skb->pkt_type))
287                         skb->pkt_type = value8;
288                 break;
289         case NFT_META_NFTRACE:
290                 value8 = nft_reg_load8(sreg);
291
292                 skb->nf_trace = !!value8;
293                 break;
294 #ifdef CONFIG_NETWORK_SECMARK
295         case NFT_META_SECMARK:
296                 skb->secmark = value;
297                 break;
298 #endif
299         default:
300                 WARN_ON(1);
301         }
302 }
303
304 static const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
305         [NFTA_META_DREG]        = { .type = NLA_U32 },
306         [NFTA_META_KEY]         = { .type = NLA_U32 },
307         [NFTA_META_SREG]        = { .type = NLA_U32 },
308 };
309
310 static int nft_meta_get_init(const struct nft_ctx *ctx,
311                              const struct nft_expr *expr,
312                              const struct nlattr * const tb[])
313 {
314         struct nft_meta *priv = nft_expr_priv(expr);
315         unsigned int len;
316
317         priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
318         switch (priv->key) {
319         case NFT_META_PROTOCOL:
320         case NFT_META_IIFTYPE:
321         case NFT_META_OIFTYPE:
322                 len = sizeof(u16);
323                 break;
324         case NFT_META_NFPROTO:
325         case NFT_META_L4PROTO:
326         case NFT_META_LEN:
327         case NFT_META_PRIORITY:
328         case NFT_META_MARK:
329         case NFT_META_IIF:
330         case NFT_META_OIF:
331         case NFT_META_SKUID:
332         case NFT_META_SKGID:
333 #ifdef CONFIG_IP_ROUTE_CLASSID
334         case NFT_META_RTCLASSID:
335 #endif
336 #ifdef CONFIG_NETWORK_SECMARK
337         case NFT_META_SECMARK:
338 #endif
339         case NFT_META_PKTTYPE:
340         case NFT_META_CPU:
341         case NFT_META_IIFGROUP:
342         case NFT_META_OIFGROUP:
343 #ifdef CONFIG_CGROUP_NET_CLASSID
344         case NFT_META_CGROUP:
345 #endif
346                 len = sizeof(u32);
347                 break;
348         case NFT_META_IIFNAME:
349         case NFT_META_OIFNAME:
350         case NFT_META_IIFKIND:
351         case NFT_META_OIFKIND:
352                 len = IFNAMSIZ;
353                 break;
354         case NFT_META_PRANDOM:
355                 prandom_init_once(&nft_prandom_state);
356                 len = sizeof(u32);
357                 break;
358 #ifdef CONFIG_XFRM
359         case NFT_META_SECPATH:
360                 len = sizeof(u8);
361                 break;
362 #endif
363 #ifdef CONFIG_NF_TABLES_BRIDGE
364         case NFT_META_BRI_IIFNAME:
365         case NFT_META_BRI_OIFNAME:
366                 if (ctx->family != NFPROTO_BRIDGE)
367                         return -EOPNOTSUPP;
368                 len = IFNAMSIZ;
369                 break;
370 #endif
371         default:
372                 return -EOPNOTSUPP;
373         }
374
375         priv->dreg = nft_parse_register(tb[NFTA_META_DREG]);
376         return nft_validate_register_store(ctx, priv->dreg, NULL,
377                                            NFT_DATA_VALUE, len);
378 }
379
380 static int nft_meta_get_validate(const struct nft_ctx *ctx,
381                                  const struct nft_expr *expr,
382                                  const struct nft_data **data)
383 {
384 #ifdef CONFIG_XFRM
385         const struct nft_meta *priv = nft_expr_priv(expr);
386         unsigned int hooks;
387
388         if (priv->key != NFT_META_SECPATH)
389                 return 0;
390
391         switch (ctx->family) {
392         case NFPROTO_NETDEV:
393                 hooks = 1 << NF_NETDEV_INGRESS;
394                 break;
395         case NFPROTO_IPV4:
396         case NFPROTO_IPV6:
397         case NFPROTO_INET:
398                 hooks = (1 << NF_INET_PRE_ROUTING) |
399                         (1 << NF_INET_LOCAL_IN) |
400                         (1 << NF_INET_FORWARD);
401                 break;
402         default:
403                 return -EOPNOTSUPP;
404         }
405
406         return nft_chain_validate_hooks(ctx->chain, hooks);
407 #else
408         return 0;
409 #endif
410 }
411
412 static int nft_meta_set_validate(const struct nft_ctx *ctx,
413                                  const struct nft_expr *expr,
414                                  const struct nft_data **data)
415 {
416         struct nft_meta *priv = nft_expr_priv(expr);
417         unsigned int hooks;
418
419         if (priv->key != NFT_META_PKTTYPE)
420                 return 0;
421
422         switch (ctx->family) {
423         case NFPROTO_BRIDGE:
424                 hooks = 1 << NF_BR_PRE_ROUTING;
425                 break;
426         case NFPROTO_NETDEV:
427                 hooks = 1 << NF_NETDEV_INGRESS;
428                 break;
429         case NFPROTO_IPV4:
430         case NFPROTO_IPV6:
431         case NFPROTO_INET:
432                 hooks = 1 << NF_INET_PRE_ROUTING;
433                 break;
434         default:
435                 return -EOPNOTSUPP;
436         }
437
438         return nft_chain_validate_hooks(ctx->chain, hooks);
439 }
440
441 static int nft_meta_set_init(const struct nft_ctx *ctx,
442                              const struct nft_expr *expr,
443                              const struct nlattr * const tb[])
444 {
445         struct nft_meta *priv = nft_expr_priv(expr);
446         unsigned int len;
447         int err;
448
449         priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
450         switch (priv->key) {
451         case NFT_META_MARK:
452         case NFT_META_PRIORITY:
453 #ifdef CONFIG_NETWORK_SECMARK
454         case NFT_META_SECMARK:
455 #endif
456                 len = sizeof(u32);
457                 break;
458         case NFT_META_NFTRACE:
459                 len = sizeof(u8);
460                 break;
461         case NFT_META_PKTTYPE:
462                 len = sizeof(u8);
463                 break;
464         default:
465                 return -EOPNOTSUPP;
466         }
467
468         priv->sreg = nft_parse_register(tb[NFTA_META_SREG]);
469         err = nft_validate_register_load(priv->sreg, len);
470         if (err < 0)
471                 return err;
472
473         if (priv->key == NFT_META_NFTRACE)
474                 static_branch_inc(&nft_trace_enabled);
475
476         return 0;
477 }
478
479 static int nft_meta_get_dump(struct sk_buff *skb,
480                              const struct nft_expr *expr)
481 {
482         const struct nft_meta *priv = nft_expr_priv(expr);
483
484         if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
485                 goto nla_put_failure;
486         if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
487                 goto nla_put_failure;
488         return 0;
489
490 nla_put_failure:
491         return -1;
492 }
493
494 static int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
495 {
496         const struct nft_meta *priv = nft_expr_priv(expr);
497
498         if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
499                 goto nla_put_failure;
500         if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg))
501                 goto nla_put_failure;
502
503         return 0;
504
505 nla_put_failure:
506         return -1;
507 }
508
509 static void nft_meta_set_destroy(const struct nft_ctx *ctx,
510                                  const struct nft_expr *expr)
511 {
512         const struct nft_meta *priv = nft_expr_priv(expr);
513
514         if (priv->key == NFT_META_NFTRACE)
515                 static_branch_dec(&nft_trace_enabled);
516 }
517
518 static const struct nft_expr_ops nft_meta_get_ops = {
519         .type           = &nft_meta_type,
520         .size           = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
521         .eval           = nft_meta_get_eval,
522         .init           = nft_meta_get_init,
523         .dump           = nft_meta_get_dump,
524         .validate       = nft_meta_get_validate,
525 };
526
527 static const struct nft_expr_ops nft_meta_set_ops = {
528         .type           = &nft_meta_type,
529         .size           = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
530         .eval           = nft_meta_set_eval,
531         .init           = nft_meta_set_init,
532         .destroy        = nft_meta_set_destroy,
533         .dump           = nft_meta_set_dump,
534         .validate       = nft_meta_set_validate,
535 };
536
537 static const struct nft_expr_ops *
538 nft_meta_select_ops(const struct nft_ctx *ctx,
539                     const struct nlattr * const tb[])
540 {
541         if (tb[NFTA_META_KEY] == NULL)
542                 return ERR_PTR(-EINVAL);
543
544         if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG])
545                 return ERR_PTR(-EINVAL);
546
547         if (tb[NFTA_META_DREG])
548                 return &nft_meta_get_ops;
549
550         if (tb[NFTA_META_SREG])
551                 return &nft_meta_set_ops;
552
553         return ERR_PTR(-EINVAL);
554 }
555
556 struct nft_expr_type nft_meta_type __read_mostly = {
557         .name           = "meta",
558         .select_ops     = nft_meta_select_ops,
559         .policy         = nft_meta_policy,
560         .maxattr        = NFTA_META_MAX,
561         .owner          = THIS_MODULE,
562 };
563
564 #ifdef CONFIG_NETWORK_SECMARK
565 struct nft_secmark {
566         u32 secid;
567         char *ctx;
568 };
569
570 static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
571         [NFTA_SECMARK_CTX]     = { .type = NLA_STRING, .len = NFT_SECMARK_CTX_MAXLEN },
572 };
573
574 static int nft_secmark_compute_secid(struct nft_secmark *priv)
575 {
576         u32 tmp_secid = 0;
577         int err;
578
579         err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid);
580         if (err)
581                 return err;
582
583         if (!tmp_secid)
584                 return -ENOENT;
585
586         err = security_secmark_relabel_packet(tmp_secid);
587         if (err)
588                 return err;
589
590         priv->secid = tmp_secid;
591         return 0;
592 }
593
594 static void nft_secmark_obj_eval(struct nft_object *obj, struct nft_regs *regs,
595                                  const struct nft_pktinfo *pkt)
596 {
597         const struct nft_secmark *priv = nft_obj_data(obj);
598         struct sk_buff *skb = pkt->skb;
599
600         skb->secmark = priv->secid;
601 }
602
603 static int nft_secmark_obj_init(const struct nft_ctx *ctx,
604                                 const struct nlattr * const tb[],
605                                 struct nft_object *obj)
606 {
607         struct nft_secmark *priv = nft_obj_data(obj);
608         int err;
609
610         if (tb[NFTA_SECMARK_CTX] == NULL)
611                 return -EINVAL;
612
613         priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL);
614         if (!priv->ctx)
615                 return -ENOMEM;
616
617         err = nft_secmark_compute_secid(priv);
618         if (err) {
619                 kfree(priv->ctx);
620                 return err;
621         }
622
623         security_secmark_refcount_inc();
624
625         return 0;
626 }
627
628 static int nft_secmark_obj_dump(struct sk_buff *skb, struct nft_object *obj,
629                                 bool reset)
630 {
631         struct nft_secmark *priv = nft_obj_data(obj);
632         int err;
633
634         if (nla_put_string(skb, NFTA_SECMARK_CTX, priv->ctx))
635                 return -1;
636
637         if (reset) {
638                 err = nft_secmark_compute_secid(priv);
639                 if (err)
640                         return err;
641         }
642
643         return 0;
644 }
645
646 static void nft_secmark_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
647 {
648         struct nft_secmark *priv = nft_obj_data(obj);
649
650         security_secmark_refcount_dec();
651
652         kfree(priv->ctx);
653 }
654
655 static const struct nft_object_ops nft_secmark_obj_ops = {
656         .type           = &nft_secmark_obj_type,
657         .size           = sizeof(struct nft_secmark),
658         .init           = nft_secmark_obj_init,
659         .eval           = nft_secmark_obj_eval,
660         .dump           = nft_secmark_obj_dump,
661         .destroy        = nft_secmark_obj_destroy,
662 };
663 struct nft_object_type nft_secmark_obj_type __read_mostly = {
664         .type           = NFT_OBJECT_SECMARK,
665         .ops            = &nft_secmark_obj_ops,
666         .maxattr        = NFTA_SECMARK_MAX,
667         .policy         = nft_secmark_policy,
668         .owner          = THIS_MODULE,
669 };
670 #endif /* CONFIG_NETWORK_SECMARK */