Merge branches 'fixes' and 'misc' into for-linus
[linux-2.6-microblaze.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/ip.h>
21 #include <net/sock.h>
22 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
23 #include <net/netfilter/nf_tables.h>
24 #include <net/netfilter/nf_tables_core.h>
25 #include <net/netfilter/nft_meta.h>
26 #include <net/netfilter/nf_tables_offload.h>
27
28 #include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
29
30 #define NFT_META_SECS_PER_MINUTE        60
31 #define NFT_META_SECS_PER_HOUR          3600
32 #define NFT_META_SECS_PER_DAY           86400
33 #define NFT_META_DAYS_PER_WEEK          7
34
35 static DEFINE_PER_CPU(struct rnd_state, nft_prandom_state);
36
37 static u8 nft_meta_weekday(void)
38 {
39         time64_t secs = ktime_get_real_seconds();
40         unsigned int dse;
41         u8 wday;
42
43         secs -= NFT_META_SECS_PER_MINUTE * sys_tz.tz_minuteswest;
44         dse = div_u64(secs, NFT_META_SECS_PER_DAY);
45         wday = (4 + dse) % NFT_META_DAYS_PER_WEEK;
46
47         return wday;
48 }
49
50 static u32 nft_meta_hour(time64_t secs)
51 {
52         struct tm tm;
53
54         time64_to_tm(secs, 0, &tm);
55
56         return tm.tm_hour * NFT_META_SECS_PER_HOUR
57                 + tm.tm_min * NFT_META_SECS_PER_MINUTE
58                 + tm.tm_sec;
59 }
60
61 static noinline_for_stack void
62 nft_meta_get_eval_time(enum nft_meta_keys key,
63                        u32 *dest)
64 {
65         switch (key) {
66         case NFT_META_TIME_NS:
67                 nft_reg_store64(dest, ktime_get_real_ns());
68                 break;
69         case NFT_META_TIME_DAY:
70                 nft_reg_store8(dest, nft_meta_weekday());
71                 break;
72         case NFT_META_TIME_HOUR:
73                 *dest = nft_meta_hour(ktime_get_real_seconds());
74                 break;
75         default:
76                 break;
77         }
78 }
79
80 static noinline bool
81 nft_meta_get_eval_pkttype_lo(const struct nft_pktinfo *pkt,
82                              u32 *dest)
83 {
84         const struct sk_buff *skb = pkt->skb;
85
86         switch (nft_pf(pkt)) {
87         case NFPROTO_IPV4:
88                 if (ipv4_is_multicast(ip_hdr(skb)->daddr))
89                         nft_reg_store8(dest, PACKET_MULTICAST);
90                 else
91                         nft_reg_store8(dest, PACKET_BROADCAST);
92                 break;
93         case NFPROTO_IPV6:
94                 nft_reg_store8(dest, PACKET_MULTICAST);
95                 break;
96         case NFPROTO_NETDEV:
97                 switch (skb->protocol) {
98                 case htons(ETH_P_IP): {
99                         int noff = skb_network_offset(skb);
100                         struct iphdr *iph, _iph;
101
102                         iph = skb_header_pointer(skb, noff,
103                                                  sizeof(_iph), &_iph);
104                         if (!iph)
105                                 return false;
106
107                         if (ipv4_is_multicast(iph->daddr))
108                                 nft_reg_store8(dest, PACKET_MULTICAST);
109                         else
110                                 nft_reg_store8(dest, PACKET_BROADCAST);
111
112                         break;
113                 }
114                 case htons(ETH_P_IPV6):
115                         nft_reg_store8(dest, PACKET_MULTICAST);
116                         break;
117                 default:
118                         WARN_ON_ONCE(1);
119                         return false;
120                 }
121                 break;
122         default:
123                 WARN_ON_ONCE(1);
124                 return false;
125         }
126
127         return true;
128 }
129
130 static noinline bool
131 nft_meta_get_eval_skugid(enum nft_meta_keys key,
132                          u32 *dest,
133                          const struct nft_pktinfo *pkt)
134 {
135         struct sock *sk = skb_to_full_sk(pkt->skb);
136         struct socket *sock;
137
138         if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
139                 return false;
140
141         read_lock_bh(&sk->sk_callback_lock);
142         sock = sk->sk_socket;
143         if (!sock || !sock->file) {
144                 read_unlock_bh(&sk->sk_callback_lock);
145                 return false;
146         }
147
148         switch (key) {
149         case NFT_META_SKUID:
150                 *dest = from_kuid_munged(sock_net(sk)->user_ns,
151                                          sock->file->f_cred->fsuid);
152                 break;
153         case NFT_META_SKGID:
154                 *dest = from_kgid_munged(sock_net(sk)->user_ns,
155                                          sock->file->f_cred->fsgid);
156                 break;
157         default:
158                 break;
159         }
160
161         read_unlock_bh(&sk->sk_callback_lock);
162         return true;
163 }
164
165 #ifdef CONFIG_CGROUP_NET_CLASSID
166 static noinline bool
167 nft_meta_get_eval_cgroup(u32 *dest, const struct nft_pktinfo *pkt)
168 {
169         struct sock *sk = skb_to_full_sk(pkt->skb);
170
171         if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
172                 return false;
173
174         *dest = sock_cgroup_classid(&sk->sk_cgrp_data);
175         return true;
176 }
177 #endif
178
179 static noinline bool nft_meta_get_eval_kind(enum nft_meta_keys key,
180                                             u32 *dest,
181                                             const struct nft_pktinfo *pkt)
182 {
183         const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
184
185         switch (key) {
186         case NFT_META_IIFKIND:
187                 if (!in || !in->rtnl_link_ops)
188                         return false;
189                 strncpy((char *)dest, in->rtnl_link_ops->kind, IFNAMSIZ);
190                 break;
191         case NFT_META_OIFKIND:
192                 if (!out || !out->rtnl_link_ops)
193                         return false;
194                 strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
195                 break;
196         default:
197                 return false;
198         }
199
200         return true;
201 }
202
203 static void nft_meta_store_ifindex(u32 *dest, const struct net_device *dev)
204 {
205         *dest = dev ? dev->ifindex : 0;
206 }
207
208 static void nft_meta_store_ifname(u32 *dest, const struct net_device *dev)
209 {
210         strncpy((char *)dest, dev ? dev->name : "", IFNAMSIZ);
211 }
212
213 static bool nft_meta_store_iftype(u32 *dest, const struct net_device *dev)
214 {
215         if (!dev)
216                 return false;
217
218         nft_reg_store16(dest, dev->type);
219         return true;
220 }
221
222 static bool nft_meta_store_ifgroup(u32 *dest, const struct net_device *dev)
223 {
224         if (!dev)
225                 return false;
226
227         *dest = dev->group;
228         return true;
229 }
230
231 static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,
232                                      const struct nft_pktinfo *pkt)
233 {
234         switch (key) {
235         case NFT_META_IIFNAME:
236                 nft_meta_store_ifname(dest, nft_in(pkt));
237                 break;
238         case NFT_META_OIFNAME:
239                 nft_meta_store_ifname(dest, nft_out(pkt));
240                 break;
241         case NFT_META_IIF:
242                 nft_meta_store_ifindex(dest, nft_in(pkt));
243                 break;
244         case NFT_META_OIF:
245                 nft_meta_store_ifindex(dest, nft_out(pkt));
246                 break;
247         case NFT_META_IFTYPE:
248                 if (!nft_meta_store_iftype(dest, pkt->skb->dev))
249                         return false;
250                 break;
251         case __NFT_META_IIFTYPE:
252                 if (!nft_meta_store_iftype(dest, nft_in(pkt)))
253                         return false;
254                 break;
255         case NFT_META_OIFTYPE:
256                 if (!nft_meta_store_iftype(dest, nft_out(pkt)))
257                         return false;
258                 break;
259         case NFT_META_IIFGROUP:
260                 if (!nft_meta_store_ifgroup(dest, nft_in(pkt)))
261                         return false;
262                 break;
263         case NFT_META_OIFGROUP:
264                 if (!nft_meta_store_ifgroup(dest, nft_out(pkt)))
265                         return false;
266                 break;
267         default:
268                 return false;
269         }
270
271         return true;
272 }
273
274 static noinline u32 nft_prandom_u32(void)
275 {
276         struct rnd_state *state = this_cpu_ptr(&nft_prandom_state);
277
278         return prandom_u32_state(state);
279 }
280
281 #ifdef CONFIG_IP_ROUTE_CLASSID
282 static noinline bool
283 nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest)
284 {
285         const struct dst_entry *dst = skb_dst(skb);
286
287         if (!dst)
288                 return false;
289
290         *dest = dst->tclassid;
291         return true;
292 }
293 #endif
294
295 static noinline u32 nft_meta_get_eval_sdif(const struct nft_pktinfo *pkt)
296 {
297         switch (nft_pf(pkt)) {
298         case NFPROTO_IPV4:
299                 return inet_sdif(pkt->skb);
300         case NFPROTO_IPV6:
301                 return inet6_sdif(pkt->skb);
302         }
303
304         return 0;
305 }
306
307 static noinline void
308 nft_meta_get_eval_sdifname(u32 *dest, const struct nft_pktinfo *pkt)
309 {
310         u32 sdif = nft_meta_get_eval_sdif(pkt);
311         const struct net_device *dev;
312
313         dev = sdif ? dev_get_by_index_rcu(nft_net(pkt), sdif) : NULL;
314         nft_meta_store_ifname(dest, dev);
315 }
316
317 void nft_meta_get_eval(const struct nft_expr *expr,
318                        struct nft_regs *regs,
319                        const struct nft_pktinfo *pkt)
320 {
321         const struct nft_meta *priv = nft_expr_priv(expr);
322         const struct sk_buff *skb = pkt->skb;
323         u32 *dest = &regs->data[priv->dreg];
324
325         switch (priv->key) {
326         case NFT_META_LEN:
327                 *dest = skb->len;
328                 break;
329         case NFT_META_PROTOCOL:
330                 nft_reg_store16(dest, (__force u16)skb->protocol);
331                 break;
332         case NFT_META_NFPROTO:
333                 nft_reg_store8(dest, nft_pf(pkt));
334                 break;
335         case NFT_META_L4PROTO:
336                 if (!(pkt->flags & NFT_PKTINFO_L4PROTO))
337                         goto err;
338                 nft_reg_store8(dest, pkt->tprot);
339                 break;
340         case NFT_META_PRIORITY:
341                 *dest = skb->priority;
342                 break;
343         case NFT_META_MARK:
344                 *dest = skb->mark;
345                 break;
346         case NFT_META_IIF:
347         case NFT_META_OIF:
348         case NFT_META_IIFNAME:
349         case NFT_META_OIFNAME:
350         case NFT_META_IIFTYPE:
351         case NFT_META_OIFTYPE:
352         case NFT_META_IIFGROUP:
353         case NFT_META_OIFGROUP:
354                 if (!nft_meta_get_eval_ifname(priv->key, dest, pkt))
355                         goto err;
356                 break;
357         case NFT_META_SKUID:
358         case NFT_META_SKGID:
359                 if (!nft_meta_get_eval_skugid(priv->key, dest, pkt))
360                         goto err;
361                 break;
362 #ifdef CONFIG_IP_ROUTE_CLASSID
363         case NFT_META_RTCLASSID:
364                 if (!nft_meta_get_eval_rtclassid(skb, dest))
365                         goto err;
366                 break;
367 #endif
368 #ifdef CONFIG_NETWORK_SECMARK
369         case NFT_META_SECMARK:
370                 *dest = skb->secmark;
371                 break;
372 #endif
373         case NFT_META_PKTTYPE:
374                 if (skb->pkt_type != PACKET_LOOPBACK) {
375                         nft_reg_store8(dest, skb->pkt_type);
376                         break;
377                 }
378
379                 if (!nft_meta_get_eval_pkttype_lo(pkt, dest))
380                         goto err;
381                 break;
382         case NFT_META_CPU:
383                 *dest = raw_smp_processor_id();
384                 break;
385 #ifdef CONFIG_CGROUP_NET_CLASSID
386         case NFT_META_CGROUP:
387                 if (!nft_meta_get_eval_cgroup(dest, pkt))
388                         goto err;
389                 break;
390 #endif
391         case NFT_META_PRANDOM:
392                 *dest = nft_prandom_u32();
393                 break;
394 #ifdef CONFIG_XFRM
395         case NFT_META_SECPATH:
396                 nft_reg_store8(dest, secpath_exists(skb));
397                 break;
398 #endif
399         case NFT_META_IIFKIND:
400         case NFT_META_OIFKIND:
401                 if (!nft_meta_get_eval_kind(priv->key, dest, pkt))
402                         goto err;
403                 break;
404         case NFT_META_TIME_NS:
405         case NFT_META_TIME_DAY:
406         case NFT_META_TIME_HOUR:
407                 nft_meta_get_eval_time(priv->key, dest);
408                 break;
409         case NFT_META_SDIF:
410                 *dest = nft_meta_get_eval_sdif(pkt);
411                 break;
412         case NFT_META_SDIFNAME:
413                 nft_meta_get_eval_sdifname(dest, pkt);
414                 break;
415         default:
416                 WARN_ON(1);
417                 goto err;
418         }
419         return;
420
421 err:
422         regs->verdict.code = NFT_BREAK;
423 }
424 EXPORT_SYMBOL_GPL(nft_meta_get_eval);
425
426 void nft_meta_set_eval(const struct nft_expr *expr,
427                        struct nft_regs *regs,
428                        const struct nft_pktinfo *pkt)
429 {
430         const struct nft_meta *meta = nft_expr_priv(expr);
431         struct sk_buff *skb = pkt->skb;
432         u32 *sreg = &regs->data[meta->sreg];
433         u32 value = *sreg;
434         u8 value8;
435
436         switch (meta->key) {
437         case NFT_META_MARK:
438                 skb->mark = value;
439                 break;
440         case NFT_META_PRIORITY:
441                 skb->priority = value;
442                 break;
443         case NFT_META_PKTTYPE:
444                 value8 = nft_reg_load8(sreg);
445
446                 if (skb->pkt_type != value8 &&
447                     skb_pkt_type_ok(value8) &&
448                     skb_pkt_type_ok(skb->pkt_type))
449                         skb->pkt_type = value8;
450                 break;
451         case NFT_META_NFTRACE:
452                 value8 = nft_reg_load8(sreg);
453
454                 skb->nf_trace = !!value8;
455                 break;
456 #ifdef CONFIG_NETWORK_SECMARK
457         case NFT_META_SECMARK:
458                 skb->secmark = value;
459                 break;
460 #endif
461         default:
462                 WARN_ON(1);
463         }
464 }
465 EXPORT_SYMBOL_GPL(nft_meta_set_eval);
466
467 const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
468         [NFTA_META_DREG]        = { .type = NLA_U32 },
469         [NFTA_META_KEY]         = { .type = NLA_U32 },
470         [NFTA_META_SREG]        = { .type = NLA_U32 },
471 };
472 EXPORT_SYMBOL_GPL(nft_meta_policy);
473
474 int nft_meta_get_init(const struct nft_ctx *ctx,
475                       const struct nft_expr *expr,
476                       const struct nlattr * const tb[])
477 {
478         struct nft_meta *priv = nft_expr_priv(expr);
479         unsigned int len;
480
481         priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
482         switch (priv->key) {
483         case NFT_META_PROTOCOL:
484         case NFT_META_IIFTYPE:
485         case NFT_META_OIFTYPE:
486                 len = sizeof(u16);
487                 break;
488         case NFT_META_NFPROTO:
489         case NFT_META_L4PROTO:
490         case NFT_META_LEN:
491         case NFT_META_PRIORITY:
492         case NFT_META_MARK:
493         case NFT_META_IIF:
494         case NFT_META_OIF:
495         case NFT_META_SDIF:
496         case NFT_META_SKUID:
497         case NFT_META_SKGID:
498 #ifdef CONFIG_IP_ROUTE_CLASSID
499         case NFT_META_RTCLASSID:
500 #endif
501 #ifdef CONFIG_NETWORK_SECMARK
502         case NFT_META_SECMARK:
503 #endif
504         case NFT_META_PKTTYPE:
505         case NFT_META_CPU:
506         case NFT_META_IIFGROUP:
507         case NFT_META_OIFGROUP:
508 #ifdef CONFIG_CGROUP_NET_CLASSID
509         case NFT_META_CGROUP:
510 #endif
511                 len = sizeof(u32);
512                 break;
513         case NFT_META_IIFNAME:
514         case NFT_META_OIFNAME:
515         case NFT_META_IIFKIND:
516         case NFT_META_OIFKIND:
517         case NFT_META_SDIFNAME:
518                 len = IFNAMSIZ;
519                 break;
520         case NFT_META_PRANDOM:
521                 prandom_init_once(&nft_prandom_state);
522                 len = sizeof(u32);
523                 break;
524 #ifdef CONFIG_XFRM
525         case NFT_META_SECPATH:
526                 len = sizeof(u8);
527                 break;
528 #endif
529         case NFT_META_TIME_NS:
530                 len = sizeof(u64);
531                 break;
532         case NFT_META_TIME_DAY:
533                 len = sizeof(u8);
534                 break;
535         case NFT_META_TIME_HOUR:
536                 len = sizeof(u32);
537                 break;
538         default:
539                 return -EOPNOTSUPP;
540         }
541
542         return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
543                                         NULL, NFT_DATA_VALUE, len);
544 }
545 EXPORT_SYMBOL_GPL(nft_meta_get_init);
546
547 static int nft_meta_get_validate_sdif(const struct nft_ctx *ctx)
548 {
549         unsigned int hooks;
550
551         switch (ctx->family) {
552         case NFPROTO_IPV4:
553         case NFPROTO_IPV6:
554         case NFPROTO_INET:
555                 hooks = (1 << NF_INET_LOCAL_IN) |
556                         (1 << NF_INET_FORWARD);
557                 break;
558         default:
559                 return -EOPNOTSUPP;
560         }
561
562         return nft_chain_validate_hooks(ctx->chain, hooks);
563 }
564
565 static int nft_meta_get_validate_xfrm(const struct nft_ctx *ctx)
566 {
567 #ifdef CONFIG_XFRM
568         unsigned int hooks;
569
570         switch (ctx->family) {
571         case NFPROTO_NETDEV:
572                 hooks = 1 << NF_NETDEV_INGRESS;
573                 break;
574         case NFPROTO_IPV4:
575         case NFPROTO_IPV6:
576         case NFPROTO_INET:
577                 hooks = (1 << NF_INET_PRE_ROUTING) |
578                         (1 << NF_INET_LOCAL_IN) |
579                         (1 << NF_INET_FORWARD);
580                 break;
581         default:
582                 return -EOPNOTSUPP;
583         }
584
585         return nft_chain_validate_hooks(ctx->chain, hooks);
586 #else
587         return 0;
588 #endif
589 }
590
591 static int nft_meta_get_validate(const struct nft_ctx *ctx,
592                                  const struct nft_expr *expr,
593                                  const struct nft_data **data)
594 {
595         const struct nft_meta *priv = nft_expr_priv(expr);
596
597         switch (priv->key) {
598         case NFT_META_SECPATH:
599                 return nft_meta_get_validate_xfrm(ctx);
600         case NFT_META_SDIF:
601         case NFT_META_SDIFNAME:
602                 return nft_meta_get_validate_sdif(ctx);
603         default:
604                 break;
605         }
606
607         return 0;
608 }
609
610 int nft_meta_set_validate(const struct nft_ctx *ctx,
611                           const struct nft_expr *expr,
612                           const struct nft_data **data)
613 {
614         struct nft_meta *priv = nft_expr_priv(expr);
615         unsigned int hooks;
616
617         if (priv->key != NFT_META_PKTTYPE)
618                 return 0;
619
620         switch (ctx->family) {
621         case NFPROTO_BRIDGE:
622                 hooks = 1 << NF_BR_PRE_ROUTING;
623                 break;
624         case NFPROTO_NETDEV:
625                 hooks = 1 << NF_NETDEV_INGRESS;
626                 break;
627         case NFPROTO_IPV4:
628         case NFPROTO_IPV6:
629         case NFPROTO_INET:
630                 hooks = 1 << NF_INET_PRE_ROUTING;
631                 break;
632         default:
633                 return -EOPNOTSUPP;
634         }
635
636         return nft_chain_validate_hooks(ctx->chain, hooks);
637 }
638 EXPORT_SYMBOL_GPL(nft_meta_set_validate);
639
640 int nft_meta_set_init(const struct nft_ctx *ctx,
641                       const struct nft_expr *expr,
642                       const struct nlattr * const tb[])
643 {
644         struct nft_meta *priv = nft_expr_priv(expr);
645         unsigned int len;
646         int err;
647
648         priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
649         switch (priv->key) {
650         case NFT_META_MARK:
651         case NFT_META_PRIORITY:
652 #ifdef CONFIG_NETWORK_SECMARK
653         case NFT_META_SECMARK:
654 #endif
655                 len = sizeof(u32);
656                 break;
657         case NFT_META_NFTRACE:
658                 len = sizeof(u8);
659                 break;
660         case NFT_META_PKTTYPE:
661                 len = sizeof(u8);
662                 break;
663         default:
664                 return -EOPNOTSUPP;
665         }
666
667         err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len);
668         if (err < 0)
669                 return err;
670
671         if (priv->key == NFT_META_NFTRACE)
672                 static_branch_inc(&nft_trace_enabled);
673
674         return 0;
675 }
676 EXPORT_SYMBOL_GPL(nft_meta_set_init);
677
678 int nft_meta_get_dump(struct sk_buff *skb,
679                       const struct nft_expr *expr)
680 {
681         const struct nft_meta *priv = nft_expr_priv(expr);
682
683         if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
684                 goto nla_put_failure;
685         if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
686                 goto nla_put_failure;
687         return 0;
688
689 nla_put_failure:
690         return -1;
691 }
692 EXPORT_SYMBOL_GPL(nft_meta_get_dump);
693
694 int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
695 {
696         const struct nft_meta *priv = nft_expr_priv(expr);
697
698         if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
699                 goto nla_put_failure;
700         if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg))
701                 goto nla_put_failure;
702
703         return 0;
704
705 nla_put_failure:
706         return -1;
707 }
708 EXPORT_SYMBOL_GPL(nft_meta_set_dump);
709
710 void nft_meta_set_destroy(const struct nft_ctx *ctx,
711                           const struct nft_expr *expr)
712 {
713         const struct nft_meta *priv = nft_expr_priv(expr);
714
715         if (priv->key == NFT_META_NFTRACE)
716                 static_branch_dec(&nft_trace_enabled);
717 }
718 EXPORT_SYMBOL_GPL(nft_meta_set_destroy);
719
720 static int nft_meta_get_offload(struct nft_offload_ctx *ctx,
721                                 struct nft_flow_rule *flow,
722                                 const struct nft_expr *expr)
723 {
724         const struct nft_meta *priv = nft_expr_priv(expr);
725         struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
726
727         switch (priv->key) {
728         case NFT_META_PROTOCOL:
729                 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, n_proto,
730                                         sizeof(__u16), reg);
731                 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
732                 break;
733         case NFT_META_L4PROTO:
734                 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
735                                         sizeof(__u8), reg);
736                 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
737                 break;
738         case NFT_META_IIF:
739                 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta,
740                                         ingress_ifindex, sizeof(__u32), reg);
741                 break;
742         case NFT_META_IIFTYPE:
743                 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta,
744                                         ingress_iftype, sizeof(__u16), reg);
745                 break;
746         default:
747                 return -EOPNOTSUPP;
748         }
749
750         return 0;
751 }
752
753 static bool nft_meta_get_reduce(struct nft_regs_track *track,
754                                 const struct nft_expr *expr)
755 {
756         const struct nft_meta *priv = nft_expr_priv(expr);
757         const struct nft_meta *meta;
758
759         if (!track->regs[priv->dreg].selector ||
760             track->regs[priv->dreg].selector->ops != expr->ops) {
761                 track->regs[priv->dreg].selector = expr;
762                 track->regs[priv->dreg].bitwise = NULL;
763                 return false;
764         }
765
766         meta = nft_expr_priv(track->regs[priv->dreg].selector);
767         if (priv->key != meta->key ||
768             priv->dreg != meta->dreg) {
769                 track->regs[priv->dreg].selector = expr;
770                 track->regs[priv->dreg].bitwise = NULL;
771                 return false;
772         }
773
774         if (!track->regs[priv->dreg].bitwise)
775                 return true;
776
777         return nft_expr_reduce_bitwise(track, expr);
778 }
779
780 static const struct nft_expr_ops nft_meta_get_ops = {
781         .type           = &nft_meta_type,
782         .size           = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
783         .eval           = nft_meta_get_eval,
784         .init           = nft_meta_get_init,
785         .dump           = nft_meta_get_dump,
786         .reduce         = nft_meta_get_reduce,
787         .validate       = nft_meta_get_validate,
788         .offload        = nft_meta_get_offload,
789 };
790
791 static bool nft_meta_set_reduce(struct nft_regs_track *track,
792                                 const struct nft_expr *expr)
793 {
794         int i;
795
796         for (i = 0; i < NFT_REG32_NUM; i++) {
797                 if (!track->regs[i].selector)
798                         continue;
799
800                 if (track->regs[i].selector->ops != &nft_meta_get_ops)
801                         continue;
802
803                 track->regs[i].selector = NULL;
804                 track->regs[i].bitwise = NULL;
805         }
806
807         return false;
808 }
809
810 static const struct nft_expr_ops nft_meta_set_ops = {
811         .type           = &nft_meta_type,
812         .size           = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
813         .eval           = nft_meta_set_eval,
814         .init           = nft_meta_set_init,
815         .destroy        = nft_meta_set_destroy,
816         .dump           = nft_meta_set_dump,
817         .reduce         = nft_meta_set_reduce,
818         .validate       = nft_meta_set_validate,
819 };
820
821 static const struct nft_expr_ops *
822 nft_meta_select_ops(const struct nft_ctx *ctx,
823                     const struct nlattr * const tb[])
824 {
825         if (tb[NFTA_META_KEY] == NULL)
826                 return ERR_PTR(-EINVAL);
827
828         if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG])
829                 return ERR_PTR(-EINVAL);
830
831 #if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE) && IS_MODULE(CONFIG_NFT_BRIDGE_META)
832         if (ctx->family == NFPROTO_BRIDGE)
833                 return ERR_PTR(-EAGAIN);
834 #endif
835         if (tb[NFTA_META_DREG])
836                 return &nft_meta_get_ops;
837
838         if (tb[NFTA_META_SREG])
839                 return &nft_meta_set_ops;
840
841         return ERR_PTR(-EINVAL);
842 }
843
844 struct nft_expr_type nft_meta_type __read_mostly = {
845         .name           = "meta",
846         .select_ops     = nft_meta_select_ops,
847         .policy         = nft_meta_policy,
848         .maxattr        = NFTA_META_MAX,
849         .owner          = THIS_MODULE,
850 };
851
852 #ifdef CONFIG_NETWORK_SECMARK
853 struct nft_secmark {
854         u32 secid;
855         char *ctx;
856 };
857
858 static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
859         [NFTA_SECMARK_CTX]     = { .type = NLA_STRING, .len = NFT_SECMARK_CTX_MAXLEN },
860 };
861
862 static int nft_secmark_compute_secid(struct nft_secmark *priv)
863 {
864         u32 tmp_secid = 0;
865         int err;
866
867         err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid);
868         if (err)
869                 return err;
870
871         if (!tmp_secid)
872                 return -ENOENT;
873
874         err = security_secmark_relabel_packet(tmp_secid);
875         if (err)
876                 return err;
877
878         priv->secid = tmp_secid;
879         return 0;
880 }
881
882 static void nft_secmark_obj_eval(struct nft_object *obj, struct nft_regs *regs,
883                                  const struct nft_pktinfo *pkt)
884 {
885         const struct nft_secmark *priv = nft_obj_data(obj);
886         struct sk_buff *skb = pkt->skb;
887
888         skb->secmark = priv->secid;
889 }
890
891 static int nft_secmark_obj_init(const struct nft_ctx *ctx,
892                                 const struct nlattr * const tb[],
893                                 struct nft_object *obj)
894 {
895         struct nft_secmark *priv = nft_obj_data(obj);
896         int err;
897
898         if (tb[NFTA_SECMARK_CTX] == NULL)
899                 return -EINVAL;
900
901         priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL);
902         if (!priv->ctx)
903                 return -ENOMEM;
904
905         err = nft_secmark_compute_secid(priv);
906         if (err) {
907                 kfree(priv->ctx);
908                 return err;
909         }
910
911         security_secmark_refcount_inc();
912
913         return 0;
914 }
915
916 static int nft_secmark_obj_dump(struct sk_buff *skb, struct nft_object *obj,
917                                 bool reset)
918 {
919         struct nft_secmark *priv = nft_obj_data(obj);
920         int err;
921
922         if (nla_put_string(skb, NFTA_SECMARK_CTX, priv->ctx))
923                 return -1;
924
925         if (reset) {
926                 err = nft_secmark_compute_secid(priv);
927                 if (err)
928                         return err;
929         }
930
931         return 0;
932 }
933
934 static void nft_secmark_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
935 {
936         struct nft_secmark *priv = nft_obj_data(obj);
937
938         security_secmark_refcount_dec();
939
940         kfree(priv->ctx);
941 }
942
943 static const struct nft_object_ops nft_secmark_obj_ops = {
944         .type           = &nft_secmark_obj_type,
945         .size           = sizeof(struct nft_secmark),
946         .init           = nft_secmark_obj_init,
947         .eval           = nft_secmark_obj_eval,
948         .dump           = nft_secmark_obj_dump,
949         .destroy        = nft_secmark_obj_destroy,
950 };
951 struct nft_object_type nft_secmark_obj_type __read_mostly = {
952         .type           = NFT_OBJECT_SECMARK,
953         .ops            = &nft_secmark_obj_ops,
954         .maxattr        = NFTA_SECMARK_MAX,
955         .policy         = nft_secmark_policy,
956         .owner          = THIS_MODULE,
957 };
958 #endif /* CONFIG_NETWORK_SECMARK */