0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/netlink.h>
0012 #include <linux/netfilter.h>
0013 #include <linux/netfilter/nf_tables.h>
0014 #include <linux/in.h>
0015 #include <linux/ip.h>
0016 #include <linux/ipv6.h>
0017 #include <linux/random.h>
0018 #include <linux/smp.h>
0019 #include <linux/static_key.h>
0020 #include <net/dst.h>
0021 #include <net/ip.h>
0022 #include <net/sock.h>
0023 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
0024 #include <net/netfilter/nf_tables.h>
0025 #include <net/netfilter/nf_tables_core.h>
0026 #include <net/netfilter/nft_meta.h>
0027 #include <net/netfilter/nf_tables_offload.h>
0028
0029 #include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
0030
0031 #define NFT_META_SECS_PER_MINUTE 60
0032 #define NFT_META_SECS_PER_HOUR 3600
0033 #define NFT_META_SECS_PER_DAY 86400
0034 #define NFT_META_DAYS_PER_WEEK 7
0035
0036 static u8 nft_meta_weekday(void)
0037 {
0038 time64_t secs = ktime_get_real_seconds();
0039 unsigned int dse;
0040 u8 wday;
0041
0042 secs -= NFT_META_SECS_PER_MINUTE * sys_tz.tz_minuteswest;
0043 dse = div_u64(secs, NFT_META_SECS_PER_DAY);
0044 wday = (4 + dse) % NFT_META_DAYS_PER_WEEK;
0045
0046 return wday;
0047 }
0048
0049 static u32 nft_meta_hour(time64_t secs)
0050 {
0051 struct tm tm;
0052
0053 time64_to_tm(secs, 0, &tm);
0054
0055 return tm.tm_hour * NFT_META_SECS_PER_HOUR
0056 + tm.tm_min * NFT_META_SECS_PER_MINUTE
0057 + tm.tm_sec;
0058 }
0059
0060 static noinline_for_stack void
0061 nft_meta_get_eval_time(enum nft_meta_keys key,
0062 u32 *dest)
0063 {
0064 switch (key) {
0065 case NFT_META_TIME_NS:
0066 nft_reg_store64(dest, ktime_get_real_ns());
0067 break;
0068 case NFT_META_TIME_DAY:
0069 nft_reg_store8(dest, nft_meta_weekday());
0070 break;
0071 case NFT_META_TIME_HOUR:
0072 *dest = nft_meta_hour(ktime_get_real_seconds());
0073 break;
0074 default:
0075 break;
0076 }
0077 }
0078
0079 static noinline bool
0080 nft_meta_get_eval_pkttype_lo(const struct nft_pktinfo *pkt,
0081 u32 *dest)
0082 {
0083 const struct sk_buff *skb = pkt->skb;
0084
0085 switch (nft_pf(pkt)) {
0086 case NFPROTO_IPV4:
0087 if (ipv4_is_multicast(ip_hdr(skb)->daddr))
0088 nft_reg_store8(dest, PACKET_MULTICAST);
0089 else
0090 nft_reg_store8(dest, PACKET_BROADCAST);
0091 break;
0092 case NFPROTO_IPV6:
0093 nft_reg_store8(dest, PACKET_MULTICAST);
0094 break;
0095 case NFPROTO_NETDEV:
0096 switch (skb->protocol) {
0097 case htons(ETH_P_IP): {
0098 int noff = skb_network_offset(skb);
0099 struct iphdr *iph, _iph;
0100
0101 iph = skb_header_pointer(skb, noff,
0102 sizeof(_iph), &_iph);
0103 if (!iph)
0104 return false;
0105
0106 if (ipv4_is_multicast(iph->daddr))
0107 nft_reg_store8(dest, PACKET_MULTICAST);
0108 else
0109 nft_reg_store8(dest, PACKET_BROADCAST);
0110
0111 break;
0112 }
0113 case htons(ETH_P_IPV6):
0114 nft_reg_store8(dest, PACKET_MULTICAST);
0115 break;
0116 default:
0117 WARN_ON_ONCE(1);
0118 return false;
0119 }
0120 break;
0121 default:
0122 WARN_ON_ONCE(1);
0123 return false;
0124 }
0125
0126 return true;
0127 }
0128
0129 static noinline bool
0130 nft_meta_get_eval_skugid(enum nft_meta_keys key,
0131 u32 *dest,
0132 const struct nft_pktinfo *pkt)
0133 {
0134 struct sock *sk = skb_to_full_sk(pkt->skb);
0135 struct socket *sock;
0136
0137 if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
0138 return false;
0139
0140 read_lock_bh(&sk->sk_callback_lock);
0141 sock = sk->sk_socket;
0142 if (!sock || !sock->file) {
0143 read_unlock_bh(&sk->sk_callback_lock);
0144 return false;
0145 }
0146
0147 switch (key) {
0148 case NFT_META_SKUID:
0149 *dest = from_kuid_munged(sock_net(sk)->user_ns,
0150 sock->file->f_cred->fsuid);
0151 break;
0152 case NFT_META_SKGID:
0153 *dest = from_kgid_munged(sock_net(sk)->user_ns,
0154 sock->file->f_cred->fsgid);
0155 break;
0156 default:
0157 break;
0158 }
0159
0160 read_unlock_bh(&sk->sk_callback_lock);
0161 return true;
0162 }
0163
0164 #ifdef CONFIG_CGROUP_NET_CLASSID
0165 static noinline bool
0166 nft_meta_get_eval_cgroup(u32 *dest, const struct nft_pktinfo *pkt)
0167 {
0168 struct sock *sk = skb_to_full_sk(pkt->skb);
0169
0170 if (!sk || !sk_fullsock(sk) || !net_eq(nft_net(pkt), sock_net(sk)))
0171 return false;
0172
0173 *dest = sock_cgroup_classid(&sk->sk_cgrp_data);
0174 return true;
0175 }
0176 #endif
0177
0178 static noinline bool nft_meta_get_eval_kind(enum nft_meta_keys key,
0179 u32 *dest,
0180 const struct nft_pktinfo *pkt)
0181 {
0182 const struct net_device *in = nft_in(pkt), *out = nft_out(pkt);
0183
0184 switch (key) {
0185 case NFT_META_IIFKIND:
0186 if (!in || !in->rtnl_link_ops)
0187 return false;
0188 strncpy((char *)dest, in->rtnl_link_ops->kind, IFNAMSIZ);
0189 break;
0190 case NFT_META_OIFKIND:
0191 if (!out || !out->rtnl_link_ops)
0192 return false;
0193 strncpy((char *)dest, out->rtnl_link_ops->kind, IFNAMSIZ);
0194 break;
0195 default:
0196 return false;
0197 }
0198
0199 return true;
0200 }
0201
0202 static void nft_meta_store_ifindex(u32 *dest, const struct net_device *dev)
0203 {
0204 *dest = dev ? dev->ifindex : 0;
0205 }
0206
0207 static void nft_meta_store_ifname(u32 *dest, const struct net_device *dev)
0208 {
0209 strncpy((char *)dest, dev ? dev->name : "", IFNAMSIZ);
0210 }
0211
0212 static bool nft_meta_store_iftype(u32 *dest, const struct net_device *dev)
0213 {
0214 if (!dev)
0215 return false;
0216
0217 nft_reg_store16(dest, dev->type);
0218 return true;
0219 }
0220
0221 static bool nft_meta_store_ifgroup(u32 *dest, const struct net_device *dev)
0222 {
0223 if (!dev)
0224 return false;
0225
0226 *dest = dev->group;
0227 return true;
0228 }
0229
0230 static bool nft_meta_get_eval_ifname(enum nft_meta_keys key, u32 *dest,
0231 const struct nft_pktinfo *pkt)
0232 {
0233 switch (key) {
0234 case NFT_META_IIFNAME:
0235 nft_meta_store_ifname(dest, nft_in(pkt));
0236 break;
0237 case NFT_META_OIFNAME:
0238 nft_meta_store_ifname(dest, nft_out(pkt));
0239 break;
0240 case NFT_META_IIF:
0241 nft_meta_store_ifindex(dest, nft_in(pkt));
0242 break;
0243 case NFT_META_OIF:
0244 nft_meta_store_ifindex(dest, nft_out(pkt));
0245 break;
0246 case NFT_META_IFTYPE:
0247 if (!nft_meta_store_iftype(dest, pkt->skb->dev))
0248 return false;
0249 break;
0250 case __NFT_META_IIFTYPE:
0251 if (!nft_meta_store_iftype(dest, nft_in(pkt)))
0252 return false;
0253 break;
0254 case NFT_META_OIFTYPE:
0255 if (!nft_meta_store_iftype(dest, nft_out(pkt)))
0256 return false;
0257 break;
0258 case NFT_META_IIFGROUP:
0259 if (!nft_meta_store_ifgroup(dest, nft_in(pkt)))
0260 return false;
0261 break;
0262 case NFT_META_OIFGROUP:
0263 if (!nft_meta_store_ifgroup(dest, nft_out(pkt)))
0264 return false;
0265 break;
0266 default:
0267 return false;
0268 }
0269
0270 return true;
0271 }
0272
0273 #ifdef CONFIG_IP_ROUTE_CLASSID
0274 static noinline bool
0275 nft_meta_get_eval_rtclassid(const struct sk_buff *skb, u32 *dest)
0276 {
0277 const struct dst_entry *dst = skb_dst(skb);
0278
0279 if (!dst)
0280 return false;
0281
0282 *dest = dst->tclassid;
0283 return true;
0284 }
0285 #endif
0286
0287 static noinline u32 nft_meta_get_eval_sdif(const struct nft_pktinfo *pkt)
0288 {
0289 switch (nft_pf(pkt)) {
0290 case NFPROTO_IPV4:
0291 return inet_sdif(pkt->skb);
0292 case NFPROTO_IPV6:
0293 return inet6_sdif(pkt->skb);
0294 }
0295
0296 return 0;
0297 }
0298
0299 static noinline void
0300 nft_meta_get_eval_sdifname(u32 *dest, const struct nft_pktinfo *pkt)
0301 {
0302 u32 sdif = nft_meta_get_eval_sdif(pkt);
0303 const struct net_device *dev;
0304
0305 dev = sdif ? dev_get_by_index_rcu(nft_net(pkt), sdif) : NULL;
0306 nft_meta_store_ifname(dest, dev);
0307 }
0308
0309 void nft_meta_get_eval(const struct nft_expr *expr,
0310 struct nft_regs *regs,
0311 const struct nft_pktinfo *pkt)
0312 {
0313 const struct nft_meta *priv = nft_expr_priv(expr);
0314 const struct sk_buff *skb = pkt->skb;
0315 u32 *dest = ®s->data[priv->dreg];
0316
0317 switch (priv->key) {
0318 case NFT_META_LEN:
0319 *dest = skb->len;
0320 break;
0321 case NFT_META_PROTOCOL:
0322 nft_reg_store16(dest, (__force u16)skb->protocol);
0323 break;
0324 case NFT_META_NFPROTO:
0325 nft_reg_store8(dest, nft_pf(pkt));
0326 break;
0327 case NFT_META_L4PROTO:
0328 if (!(pkt->flags & NFT_PKTINFO_L4PROTO))
0329 goto err;
0330 nft_reg_store8(dest, pkt->tprot);
0331 break;
0332 case NFT_META_PRIORITY:
0333 *dest = skb->priority;
0334 break;
0335 case NFT_META_MARK:
0336 *dest = skb->mark;
0337 break;
0338 case NFT_META_IIF:
0339 case NFT_META_OIF:
0340 case NFT_META_IIFNAME:
0341 case NFT_META_OIFNAME:
0342 case NFT_META_IIFTYPE:
0343 case NFT_META_OIFTYPE:
0344 case NFT_META_IIFGROUP:
0345 case NFT_META_OIFGROUP:
0346 if (!nft_meta_get_eval_ifname(priv->key, dest, pkt))
0347 goto err;
0348 break;
0349 case NFT_META_SKUID:
0350 case NFT_META_SKGID:
0351 if (!nft_meta_get_eval_skugid(priv->key, dest, pkt))
0352 goto err;
0353 break;
0354 #ifdef CONFIG_IP_ROUTE_CLASSID
0355 case NFT_META_RTCLASSID:
0356 if (!nft_meta_get_eval_rtclassid(skb, dest))
0357 goto err;
0358 break;
0359 #endif
0360 #ifdef CONFIG_NETWORK_SECMARK
0361 case NFT_META_SECMARK:
0362 *dest = skb->secmark;
0363 break;
0364 #endif
0365 case NFT_META_PKTTYPE:
0366 if (skb->pkt_type != PACKET_LOOPBACK) {
0367 nft_reg_store8(dest, skb->pkt_type);
0368 break;
0369 }
0370
0371 if (!nft_meta_get_eval_pkttype_lo(pkt, dest))
0372 goto err;
0373 break;
0374 case NFT_META_CPU:
0375 *dest = raw_smp_processor_id();
0376 break;
0377 #ifdef CONFIG_CGROUP_NET_CLASSID
0378 case NFT_META_CGROUP:
0379 if (!nft_meta_get_eval_cgroup(dest, pkt))
0380 goto err;
0381 break;
0382 #endif
0383 case NFT_META_PRANDOM:
0384 *dest = get_random_u32();
0385 break;
0386 #ifdef CONFIG_XFRM
0387 case NFT_META_SECPATH:
0388 nft_reg_store8(dest, secpath_exists(skb));
0389 break;
0390 #endif
0391 case NFT_META_IIFKIND:
0392 case NFT_META_OIFKIND:
0393 if (!nft_meta_get_eval_kind(priv->key, dest, pkt))
0394 goto err;
0395 break;
0396 case NFT_META_TIME_NS:
0397 case NFT_META_TIME_DAY:
0398 case NFT_META_TIME_HOUR:
0399 nft_meta_get_eval_time(priv->key, dest);
0400 break;
0401 case NFT_META_SDIF:
0402 *dest = nft_meta_get_eval_sdif(pkt);
0403 break;
0404 case NFT_META_SDIFNAME:
0405 nft_meta_get_eval_sdifname(dest, pkt);
0406 break;
0407 default:
0408 WARN_ON(1);
0409 goto err;
0410 }
0411 return;
0412
0413 err:
0414 regs->verdict.code = NFT_BREAK;
0415 }
0416 EXPORT_SYMBOL_GPL(nft_meta_get_eval);
0417
0418 void nft_meta_set_eval(const struct nft_expr *expr,
0419 struct nft_regs *regs,
0420 const struct nft_pktinfo *pkt)
0421 {
0422 const struct nft_meta *meta = nft_expr_priv(expr);
0423 struct sk_buff *skb = pkt->skb;
0424 u32 *sreg = ®s->data[meta->sreg];
0425 u32 value = *sreg;
0426 u8 value8;
0427
0428 switch (meta->key) {
0429 case NFT_META_MARK:
0430 skb->mark = value;
0431 break;
0432 case NFT_META_PRIORITY:
0433 skb->priority = value;
0434 break;
0435 case NFT_META_PKTTYPE:
0436 value8 = nft_reg_load8(sreg);
0437
0438 if (skb->pkt_type != value8 &&
0439 skb_pkt_type_ok(value8) &&
0440 skb_pkt_type_ok(skb->pkt_type))
0441 skb->pkt_type = value8;
0442 break;
0443 case NFT_META_NFTRACE:
0444 value8 = nft_reg_load8(sreg);
0445
0446 skb->nf_trace = !!value8;
0447 break;
0448 #ifdef CONFIG_NETWORK_SECMARK
0449 case NFT_META_SECMARK:
0450 skb->secmark = value;
0451 break;
0452 #endif
0453 default:
0454 WARN_ON(1);
0455 }
0456 }
0457 EXPORT_SYMBOL_GPL(nft_meta_set_eval);
0458
0459 const struct nla_policy nft_meta_policy[NFTA_META_MAX + 1] = {
0460 [NFTA_META_DREG] = { .type = NLA_U32 },
0461 [NFTA_META_KEY] = { .type = NLA_U32 },
0462 [NFTA_META_SREG] = { .type = NLA_U32 },
0463 };
0464 EXPORT_SYMBOL_GPL(nft_meta_policy);
0465
0466 int nft_meta_get_init(const struct nft_ctx *ctx,
0467 const struct nft_expr *expr,
0468 const struct nlattr * const tb[])
0469 {
0470 struct nft_meta *priv = nft_expr_priv(expr);
0471 unsigned int len;
0472
0473 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
0474 switch (priv->key) {
0475 case NFT_META_PROTOCOL:
0476 case NFT_META_IIFTYPE:
0477 case NFT_META_OIFTYPE:
0478 len = sizeof(u16);
0479 break;
0480 case NFT_META_NFPROTO:
0481 case NFT_META_L4PROTO:
0482 case NFT_META_LEN:
0483 case NFT_META_PRIORITY:
0484 case NFT_META_MARK:
0485 case NFT_META_IIF:
0486 case NFT_META_OIF:
0487 case NFT_META_SDIF:
0488 case NFT_META_SKUID:
0489 case NFT_META_SKGID:
0490 #ifdef CONFIG_IP_ROUTE_CLASSID
0491 case NFT_META_RTCLASSID:
0492 #endif
0493 #ifdef CONFIG_NETWORK_SECMARK
0494 case NFT_META_SECMARK:
0495 #endif
0496 case NFT_META_PKTTYPE:
0497 case NFT_META_CPU:
0498 case NFT_META_IIFGROUP:
0499 case NFT_META_OIFGROUP:
0500 #ifdef CONFIG_CGROUP_NET_CLASSID
0501 case NFT_META_CGROUP:
0502 #endif
0503 len = sizeof(u32);
0504 break;
0505 case NFT_META_IIFNAME:
0506 case NFT_META_OIFNAME:
0507 case NFT_META_IIFKIND:
0508 case NFT_META_OIFKIND:
0509 case NFT_META_SDIFNAME:
0510 len = IFNAMSIZ;
0511 break;
0512 case NFT_META_PRANDOM:
0513 len = sizeof(u32);
0514 break;
0515 #ifdef CONFIG_XFRM
0516 case NFT_META_SECPATH:
0517 len = sizeof(u8);
0518 break;
0519 #endif
0520 case NFT_META_TIME_NS:
0521 len = sizeof(u64);
0522 break;
0523 case NFT_META_TIME_DAY:
0524 len = sizeof(u8);
0525 break;
0526 case NFT_META_TIME_HOUR:
0527 len = sizeof(u32);
0528 break;
0529 default:
0530 return -EOPNOTSUPP;
0531 }
0532
0533 priv->len = len;
0534 return nft_parse_register_store(ctx, tb[NFTA_META_DREG], &priv->dreg,
0535 NULL, NFT_DATA_VALUE, len);
0536 }
0537 EXPORT_SYMBOL_GPL(nft_meta_get_init);
0538
0539 static int nft_meta_get_validate_sdif(const struct nft_ctx *ctx)
0540 {
0541 unsigned int hooks;
0542
0543 switch (ctx->family) {
0544 case NFPROTO_IPV4:
0545 case NFPROTO_IPV6:
0546 case NFPROTO_INET:
0547 hooks = (1 << NF_INET_LOCAL_IN) |
0548 (1 << NF_INET_FORWARD);
0549 break;
0550 default:
0551 return -EOPNOTSUPP;
0552 }
0553
0554 return nft_chain_validate_hooks(ctx->chain, hooks);
0555 }
0556
0557 static int nft_meta_get_validate_xfrm(const struct nft_ctx *ctx)
0558 {
0559 #ifdef CONFIG_XFRM
0560 unsigned int hooks;
0561
0562 switch (ctx->family) {
0563 case NFPROTO_NETDEV:
0564 hooks = 1 << NF_NETDEV_INGRESS;
0565 break;
0566 case NFPROTO_IPV4:
0567 case NFPROTO_IPV6:
0568 case NFPROTO_INET:
0569 hooks = (1 << NF_INET_PRE_ROUTING) |
0570 (1 << NF_INET_LOCAL_IN) |
0571 (1 << NF_INET_FORWARD);
0572 break;
0573 default:
0574 return -EOPNOTSUPP;
0575 }
0576
0577 return nft_chain_validate_hooks(ctx->chain, hooks);
0578 #else
0579 return 0;
0580 #endif
0581 }
0582
0583 static int nft_meta_get_validate(const struct nft_ctx *ctx,
0584 const struct nft_expr *expr,
0585 const struct nft_data **data)
0586 {
0587 const struct nft_meta *priv = nft_expr_priv(expr);
0588
0589 switch (priv->key) {
0590 case NFT_META_SECPATH:
0591 return nft_meta_get_validate_xfrm(ctx);
0592 case NFT_META_SDIF:
0593 case NFT_META_SDIFNAME:
0594 return nft_meta_get_validate_sdif(ctx);
0595 default:
0596 break;
0597 }
0598
0599 return 0;
0600 }
0601
0602 int nft_meta_set_validate(const struct nft_ctx *ctx,
0603 const struct nft_expr *expr,
0604 const struct nft_data **data)
0605 {
0606 struct nft_meta *priv = nft_expr_priv(expr);
0607 unsigned int hooks;
0608
0609 if (priv->key != NFT_META_PKTTYPE)
0610 return 0;
0611
0612 switch (ctx->family) {
0613 case NFPROTO_BRIDGE:
0614 hooks = 1 << NF_BR_PRE_ROUTING;
0615 break;
0616 case NFPROTO_NETDEV:
0617 hooks = 1 << NF_NETDEV_INGRESS;
0618 break;
0619 case NFPROTO_IPV4:
0620 case NFPROTO_IPV6:
0621 case NFPROTO_INET:
0622 hooks = 1 << NF_INET_PRE_ROUTING;
0623 break;
0624 default:
0625 return -EOPNOTSUPP;
0626 }
0627
0628 return nft_chain_validate_hooks(ctx->chain, hooks);
0629 }
0630 EXPORT_SYMBOL_GPL(nft_meta_set_validate);
0631
0632 int nft_meta_set_init(const struct nft_ctx *ctx,
0633 const struct nft_expr *expr,
0634 const struct nlattr * const tb[])
0635 {
0636 struct nft_meta *priv = nft_expr_priv(expr);
0637 unsigned int len;
0638 int err;
0639
0640 priv->key = ntohl(nla_get_be32(tb[NFTA_META_KEY]));
0641 switch (priv->key) {
0642 case NFT_META_MARK:
0643 case NFT_META_PRIORITY:
0644 #ifdef CONFIG_NETWORK_SECMARK
0645 case NFT_META_SECMARK:
0646 #endif
0647 len = sizeof(u32);
0648 break;
0649 case NFT_META_NFTRACE:
0650 len = sizeof(u8);
0651 break;
0652 case NFT_META_PKTTYPE:
0653 len = sizeof(u8);
0654 break;
0655 default:
0656 return -EOPNOTSUPP;
0657 }
0658
0659 priv->len = len;
0660 err = nft_parse_register_load(tb[NFTA_META_SREG], &priv->sreg, len);
0661 if (err < 0)
0662 return err;
0663
0664 if (priv->key == NFT_META_NFTRACE)
0665 static_branch_inc(&nft_trace_enabled);
0666
0667 return 0;
0668 }
0669 EXPORT_SYMBOL_GPL(nft_meta_set_init);
0670
0671 int nft_meta_get_dump(struct sk_buff *skb,
0672 const struct nft_expr *expr)
0673 {
0674 const struct nft_meta *priv = nft_expr_priv(expr);
0675
0676 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
0677 goto nla_put_failure;
0678 if (nft_dump_register(skb, NFTA_META_DREG, priv->dreg))
0679 goto nla_put_failure;
0680 return 0;
0681
0682 nla_put_failure:
0683 return -1;
0684 }
0685 EXPORT_SYMBOL_GPL(nft_meta_get_dump);
0686
0687 int nft_meta_set_dump(struct sk_buff *skb, const struct nft_expr *expr)
0688 {
0689 const struct nft_meta *priv = nft_expr_priv(expr);
0690
0691 if (nla_put_be32(skb, NFTA_META_KEY, htonl(priv->key)))
0692 goto nla_put_failure;
0693 if (nft_dump_register(skb, NFTA_META_SREG, priv->sreg))
0694 goto nla_put_failure;
0695
0696 return 0;
0697
0698 nla_put_failure:
0699 return -1;
0700 }
0701 EXPORT_SYMBOL_GPL(nft_meta_set_dump);
0702
0703 void nft_meta_set_destroy(const struct nft_ctx *ctx,
0704 const struct nft_expr *expr)
0705 {
0706 const struct nft_meta *priv = nft_expr_priv(expr);
0707
0708 if (priv->key == NFT_META_NFTRACE)
0709 static_branch_dec(&nft_trace_enabled);
0710 }
0711 EXPORT_SYMBOL_GPL(nft_meta_set_destroy);
0712
0713 static int nft_meta_get_offload(struct nft_offload_ctx *ctx,
0714 struct nft_flow_rule *flow,
0715 const struct nft_expr *expr)
0716 {
0717 const struct nft_meta *priv = nft_expr_priv(expr);
0718 struct nft_offload_reg *reg = &ctx->regs[priv->dreg];
0719
0720 switch (priv->key) {
0721 case NFT_META_PROTOCOL:
0722 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, n_proto,
0723 sizeof(__u16), reg);
0724 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_NETWORK);
0725 break;
0726 case NFT_META_L4PROTO:
0727 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC, basic, ip_proto,
0728 sizeof(__u8), reg);
0729 nft_offload_set_dependency(ctx, NFT_OFFLOAD_DEP_TRANSPORT);
0730 break;
0731 case NFT_META_IIF:
0732 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta,
0733 ingress_ifindex, sizeof(__u32), reg);
0734 break;
0735 case NFT_META_IIFTYPE:
0736 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META, meta,
0737 ingress_iftype, sizeof(__u16), reg);
0738 break;
0739 default:
0740 return -EOPNOTSUPP;
0741 }
0742
0743 return 0;
0744 }
0745
0746 bool nft_meta_get_reduce(struct nft_regs_track *track,
0747 const struct nft_expr *expr)
0748 {
0749 const struct nft_meta *priv = nft_expr_priv(expr);
0750 const struct nft_meta *meta;
0751
0752 if (!nft_reg_track_cmp(track, expr, priv->dreg)) {
0753 nft_reg_track_update(track, expr, priv->dreg, priv->len);
0754 return false;
0755 }
0756
0757 meta = nft_expr_priv(track->regs[priv->dreg].selector);
0758 if (priv->key != meta->key ||
0759 priv->dreg != meta->dreg) {
0760 nft_reg_track_update(track, expr, priv->dreg, priv->len);
0761 return false;
0762 }
0763
0764 if (!track->regs[priv->dreg].bitwise)
0765 return true;
0766
0767 return nft_expr_reduce_bitwise(track, expr);
0768 }
0769 EXPORT_SYMBOL_GPL(nft_meta_get_reduce);
0770
0771 static const struct nft_expr_ops nft_meta_get_ops = {
0772 .type = &nft_meta_type,
0773 .size = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
0774 .eval = nft_meta_get_eval,
0775 .init = nft_meta_get_init,
0776 .dump = nft_meta_get_dump,
0777 .reduce = nft_meta_get_reduce,
0778 .validate = nft_meta_get_validate,
0779 .offload = nft_meta_get_offload,
0780 };
0781
0782 static bool nft_meta_set_reduce(struct nft_regs_track *track,
0783 const struct nft_expr *expr)
0784 {
0785 int i;
0786
0787 for (i = 0; i < NFT_REG32_NUM; i++) {
0788 if (!track->regs[i].selector)
0789 continue;
0790
0791 if (track->regs[i].selector->ops != &nft_meta_get_ops)
0792 continue;
0793
0794 __nft_reg_track_cancel(track, i);
0795 }
0796
0797 return false;
0798 }
0799
0800 static const struct nft_expr_ops nft_meta_set_ops = {
0801 .type = &nft_meta_type,
0802 .size = NFT_EXPR_SIZE(sizeof(struct nft_meta)),
0803 .eval = nft_meta_set_eval,
0804 .init = nft_meta_set_init,
0805 .destroy = nft_meta_set_destroy,
0806 .dump = nft_meta_set_dump,
0807 .reduce = nft_meta_set_reduce,
0808 .validate = nft_meta_set_validate,
0809 };
0810
0811 static const struct nft_expr_ops *
0812 nft_meta_select_ops(const struct nft_ctx *ctx,
0813 const struct nlattr * const tb[])
0814 {
0815 if (tb[NFTA_META_KEY] == NULL)
0816 return ERR_PTR(-EINVAL);
0817
0818 if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG])
0819 return ERR_PTR(-EINVAL);
0820
0821 #if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE) && IS_MODULE(CONFIG_NFT_BRIDGE_META)
0822 if (ctx->family == NFPROTO_BRIDGE)
0823 return ERR_PTR(-EAGAIN);
0824 #endif
0825 if (tb[NFTA_META_DREG])
0826 return &nft_meta_get_ops;
0827
0828 if (tb[NFTA_META_SREG])
0829 return &nft_meta_set_ops;
0830
0831 return ERR_PTR(-EINVAL);
0832 }
0833
0834 struct nft_expr_type nft_meta_type __read_mostly = {
0835 .name = "meta",
0836 .select_ops = nft_meta_select_ops,
0837 .policy = nft_meta_policy,
0838 .maxattr = NFTA_META_MAX,
0839 .owner = THIS_MODULE,
0840 };
0841
0842 #ifdef CONFIG_NETWORK_SECMARK
0843 struct nft_secmark {
0844 u32 secid;
0845 char *ctx;
0846 };
0847
0848 static const struct nla_policy nft_secmark_policy[NFTA_SECMARK_MAX + 1] = {
0849 [NFTA_SECMARK_CTX] = { .type = NLA_STRING, .len = NFT_SECMARK_CTX_MAXLEN },
0850 };
0851
0852 static int nft_secmark_compute_secid(struct nft_secmark *priv)
0853 {
0854 u32 tmp_secid = 0;
0855 int err;
0856
0857 err = security_secctx_to_secid(priv->ctx, strlen(priv->ctx), &tmp_secid);
0858 if (err)
0859 return err;
0860
0861 if (!tmp_secid)
0862 return -ENOENT;
0863
0864 err = security_secmark_relabel_packet(tmp_secid);
0865 if (err)
0866 return err;
0867
0868 priv->secid = tmp_secid;
0869 return 0;
0870 }
0871
0872 static void nft_secmark_obj_eval(struct nft_object *obj, struct nft_regs *regs,
0873 const struct nft_pktinfo *pkt)
0874 {
0875 const struct nft_secmark *priv = nft_obj_data(obj);
0876 struct sk_buff *skb = pkt->skb;
0877
0878 skb->secmark = priv->secid;
0879 }
0880
0881 static int nft_secmark_obj_init(const struct nft_ctx *ctx,
0882 const struct nlattr * const tb[],
0883 struct nft_object *obj)
0884 {
0885 struct nft_secmark *priv = nft_obj_data(obj);
0886 int err;
0887
0888 if (tb[NFTA_SECMARK_CTX] == NULL)
0889 return -EINVAL;
0890
0891 priv->ctx = nla_strdup(tb[NFTA_SECMARK_CTX], GFP_KERNEL);
0892 if (!priv->ctx)
0893 return -ENOMEM;
0894
0895 err = nft_secmark_compute_secid(priv);
0896 if (err) {
0897 kfree(priv->ctx);
0898 return err;
0899 }
0900
0901 security_secmark_refcount_inc();
0902
0903 return 0;
0904 }
0905
0906 static int nft_secmark_obj_dump(struct sk_buff *skb, struct nft_object *obj,
0907 bool reset)
0908 {
0909 struct nft_secmark *priv = nft_obj_data(obj);
0910 int err;
0911
0912 if (nla_put_string(skb, NFTA_SECMARK_CTX, priv->ctx))
0913 return -1;
0914
0915 if (reset) {
0916 err = nft_secmark_compute_secid(priv);
0917 if (err)
0918 return err;
0919 }
0920
0921 return 0;
0922 }
0923
0924 static void nft_secmark_obj_destroy(const struct nft_ctx *ctx, struct nft_object *obj)
0925 {
0926 struct nft_secmark *priv = nft_obj_data(obj);
0927
0928 security_secmark_refcount_dec();
0929
0930 kfree(priv->ctx);
0931 }
0932
0933 static const struct nft_object_ops nft_secmark_obj_ops = {
0934 .type = &nft_secmark_obj_type,
0935 .size = sizeof(struct nft_secmark),
0936 .init = nft_secmark_obj_init,
0937 .eval = nft_secmark_obj_eval,
0938 .dump = nft_secmark_obj_dump,
0939 .destroy = nft_secmark_obj_destroy,
0940 };
0941 struct nft_object_type nft_secmark_obj_type __read_mostly = {
0942 .type = NFT_OBJECT_SECMARK,
0943 .ops = &nft_secmark_obj_ops,
0944 .maxattr = NFTA_SECMARK_MAX,
0945 .policy = nft_secmark_policy,
0946 .owner = THIS_MODULE,
0947 };
0948 #endif