1 // SPDX-License-Identifier: GPL-2.0-only
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>
7 * Development of this code funded by Astaro AG (http://www.astaro.com/)
10 #include <linux/kernel.h>
11 #include <linux/netlink.h>
12 #include <linux/netfilter.h>
13 #include <linux/netfilter/nf_tables.h>
16 #include <linux/ipv6.h>
17 #include <linux/random.h>
18 #include <linux/smp.h>
19 #include <linux/static_key.h>
23 #include <net/tcp_states.h> /* for TCP_TIME_WAIT */
24 #include <net/netfilter/nf_tables.h>
25 #include <net/netfilter/nf_tables_core.h>
26 #include <net/netfilter/nft_meta.h>
27 #include <net/netfilter/nf_tables_offload.h>
29 #include <uapi/linux/netfilter_bridge.h> /* NF_BR_PRE_ROUTING */
31 #define NFT_META_SECS_PER_MINUTE 60
32 #define NFT_META_SECS_PER_HOUR 3600
33 #define NFT_META_SECS_PER_DAY 86400
34 #define NFT_META_DAYS_PER_WEEK 7
36 static u8
nft_meta_weekday(void)
38 time64_t secs
= ktime_get_real_seconds();
42 secs
-= NFT_META_SECS_PER_MINUTE
* sys_tz
.tz_minuteswest
;
43 dse
= div_u64(secs
, NFT_META_SECS_PER_DAY
);
44 wday
= (4 + dse
) % NFT_META_DAYS_PER_WEEK
;
49 static u32
nft_meta_hour(time64_t secs
)
53 time64_to_tm(secs
, 0, &tm
);
55 return tm
.tm_hour
* NFT_META_SECS_PER_HOUR
56 + tm
.tm_min
* NFT_META_SECS_PER_MINUTE
60 static noinline_for_stack
void
61 nft_meta_get_eval_time(enum nft_meta_keys key
,
65 case NFT_META_TIME_NS
:
66 nft_reg_store64((u64
*)dest
, ktime_get_real_ns());
68 case NFT_META_TIME_DAY
:
69 nft_reg_store8(dest
, nft_meta_weekday());
71 case NFT_META_TIME_HOUR
:
72 *dest
= nft_meta_hour(ktime_get_real_seconds());
80 nft_meta_get_eval_pkttype_lo(const struct nft_pktinfo
*pkt
,
83 const struct sk_buff
*skb
= pkt
->skb
;
85 switch (nft_pf(pkt
)) {
87 if (ipv4_is_multicast(ip_hdr(skb
)->daddr
))
88 nft_reg_store8(dest
, PACKET_MULTICAST
);
90 nft_reg_store8(dest
, PACKET_BROADCAST
);
93 nft_reg_store8(dest
, PACKET_MULTICAST
);
96 switch (skb
->protocol
) {
97 case htons(ETH_P_IP
): {
98 int noff
= skb_network_offset(skb
);
99 struct iphdr
*iph
, _iph
;
101 iph
= skb_header_pointer(skb
, noff
,
102 sizeof(_iph
), &_iph
);
106 if (ipv4_is_multicast(iph
->daddr
))
107 nft_reg_store8(dest
, PACKET_MULTICAST
);
109 nft_reg_store8(dest
, PACKET_BROADCAST
);
113 case htons(ETH_P_IPV6
):
114 nft_reg_store8(dest
, PACKET_MULTICAST
);
130 nft_meta_get_eval_skugid(enum nft_meta_keys key
,
132 const struct nft_pktinfo
*pkt
)
134 struct sock
*sk
= skb_to_full_sk(pkt
->skb
);
137 if (!sk
|| !sk_fullsock(sk
) || !net_eq(nft_net(pkt
), sock_net(sk
)))
140 read_lock_bh(&sk
->sk_callback_lock
);
141 sock
= sk
->sk_socket
;
142 if (!sock
|| !sock
->file
) {
143 read_unlock_bh(&sk
->sk_callback_lock
);
149 *dest
= from_kuid_munged(sock_net(sk
)->user_ns
,
150 sock
->file
->f_cred
->fsuid
);
153 *dest
= from_kgid_munged(sock_net(sk
)->user_ns
,
154 sock
->file
->f_cred
->fsgid
);
160 read_unlock_bh(&sk
->sk_callback_lock
);
164 #ifdef CONFIG_CGROUP_NET_CLASSID
166 nft_meta_get_eval_cgroup(u32
*dest
, const struct nft_pktinfo
*pkt
)
168 struct sock
*sk
= skb_to_full_sk(pkt
->skb
);
170 if (!sk
|| !sk_fullsock(sk
) || !net_eq(nft_net(pkt
), sock_net(sk
)))
173 *dest
= sock_cgroup_classid(&sk
->sk_cgrp_data
);
178 static noinline
bool nft_meta_get_eval_kind(enum nft_meta_keys key
,
180 const struct nft_pktinfo
*pkt
)
182 const struct net_device
*in
= nft_in(pkt
), *out
= nft_out(pkt
);
185 case NFT_META_IIFKIND
:
186 if (!in
|| !in
->rtnl_link_ops
)
188 strscpy_pad((char *)dest
, in
->rtnl_link_ops
->kind
, IFNAMSIZ
);
190 case NFT_META_OIFKIND
:
191 if (!out
|| !out
->rtnl_link_ops
)
193 strscpy_pad((char *)dest
, out
->rtnl_link_ops
->kind
, IFNAMSIZ
);
202 static void nft_meta_store_ifindex(u32
*dest
, const struct net_device
*dev
)
204 *dest
= dev
? dev
->ifindex
: 0;
207 static void nft_meta_store_ifname(u32
*dest
, const struct net_device
*dev
)
209 strscpy_pad((char *)dest
, dev
? dev
->name
: "", IFNAMSIZ
);
212 static bool nft_meta_store_iftype(u32
*dest
, const struct net_device
*dev
)
217 nft_reg_store16(dest
, dev
->type
);
221 static bool nft_meta_store_ifgroup(u32
*dest
, const struct net_device
*dev
)
230 static bool nft_meta_get_eval_ifname(enum nft_meta_keys key
, u32
*dest
,
231 const struct nft_pktinfo
*pkt
)
234 case NFT_META_IIFNAME
:
235 nft_meta_store_ifname(dest
, nft_in(pkt
));
237 case NFT_META_OIFNAME
:
238 nft_meta_store_ifname(dest
, nft_out(pkt
));
241 nft_meta_store_ifindex(dest
, nft_in(pkt
));
244 nft_meta_store_ifindex(dest
, nft_out(pkt
));
246 case NFT_META_IFTYPE
:
247 if (!nft_meta_store_iftype(dest
, pkt
->skb
->dev
))
250 case __NFT_META_IIFTYPE
:
251 if (!nft_meta_store_iftype(dest
, nft_in(pkt
)))
254 case NFT_META_OIFTYPE
:
255 if (!nft_meta_store_iftype(dest
, nft_out(pkt
)))
258 case NFT_META_IIFGROUP
:
259 if (!nft_meta_store_ifgroup(dest
, nft_in(pkt
)))
262 case NFT_META_OIFGROUP
:
263 if (!nft_meta_store_ifgroup(dest
, nft_out(pkt
)))
273 #ifdef CONFIG_IP_ROUTE_CLASSID
275 nft_meta_get_eval_rtclassid(const struct sk_buff
*skb
, u32
*dest
)
277 const struct dst_entry
*dst
= skb_dst(skb
);
282 *dest
= dst
->tclassid
;
287 static noinline u32
nft_meta_get_eval_sdif(const struct nft_pktinfo
*pkt
)
289 switch (nft_pf(pkt
)) {
291 return inet_sdif(pkt
->skb
);
293 return inet6_sdif(pkt
->skb
);
300 nft_meta_get_eval_sdifname(u32
*dest
, const struct nft_pktinfo
*pkt
)
302 u32 sdif
= nft_meta_get_eval_sdif(pkt
);
303 const struct net_device
*dev
;
305 dev
= sdif
? dev_get_by_index_rcu(nft_net(pkt
), sdif
) : NULL
;
306 nft_meta_store_ifname(dest
, dev
);
309 void nft_meta_get_eval(const struct nft_expr
*expr
,
310 struct nft_regs
*regs
,
311 const struct nft_pktinfo
*pkt
)
313 const struct nft_meta
*priv
= nft_expr_priv(expr
);
314 const struct sk_buff
*skb
= pkt
->skb
;
315 u32
*dest
= ®s
->data
[priv
->dreg
];
321 case NFT_META_PROTOCOL
:
322 nft_reg_store16(dest
, (__force u16
)skb
->protocol
);
324 case NFT_META_NFPROTO
:
325 nft_reg_store8(dest
, nft_pf(pkt
));
327 case NFT_META_L4PROTO
:
328 if (!(pkt
->flags
& NFT_PKTINFO_L4PROTO
))
330 nft_reg_store8(dest
, pkt
->tprot
);
332 case NFT_META_PRIORITY
:
333 *dest
= skb
->priority
;
340 case NFT_META_IIFNAME
:
341 case NFT_META_OIFNAME
:
342 case NFT_META_IIFTYPE
:
343 case NFT_META_OIFTYPE
:
344 case NFT_META_IIFGROUP
:
345 case NFT_META_OIFGROUP
:
346 if (!nft_meta_get_eval_ifname(priv
->key
, dest
, pkt
))
351 if (!nft_meta_get_eval_skugid(priv
->key
, dest
, pkt
))
354 #ifdef CONFIG_IP_ROUTE_CLASSID
355 case NFT_META_RTCLASSID
:
356 if (!nft_meta_get_eval_rtclassid(skb
, dest
))
360 #ifdef CONFIG_NETWORK_SECMARK
361 case NFT_META_SECMARK
:
362 *dest
= skb
->secmark
;
365 case NFT_META_PKTTYPE
:
366 if (skb
->pkt_type
!= PACKET_LOOPBACK
) {
367 nft_reg_store8(dest
, skb
->pkt_type
);
371 if (!nft_meta_get_eval_pkttype_lo(pkt
, dest
))
375 *dest
= raw_smp_processor_id();
377 #ifdef CONFIG_CGROUP_NET_CLASSID
378 case NFT_META_CGROUP
:
379 if (!nft_meta_get_eval_cgroup(dest
, pkt
))
383 case NFT_META_PRANDOM
:
384 *dest
= get_random_u32();
387 case NFT_META_SECPATH
:
388 nft_reg_store8(dest
, secpath_exists(skb
));
391 case NFT_META_IIFKIND
:
392 case NFT_META_OIFKIND
:
393 if (!nft_meta_get_eval_kind(priv
->key
, dest
, pkt
))
396 case NFT_META_TIME_NS
:
397 case NFT_META_TIME_DAY
:
398 case NFT_META_TIME_HOUR
:
399 nft_meta_get_eval_time(priv
->key
, dest
);
402 *dest
= nft_meta_get_eval_sdif(pkt
);
404 case NFT_META_SDIFNAME
:
405 nft_meta_get_eval_sdifname(dest
, pkt
);
414 regs
->verdict
.code
= NFT_BREAK
;
416 EXPORT_SYMBOL_GPL(nft_meta_get_eval
);
418 void nft_meta_set_eval(const struct nft_expr
*expr
,
419 struct nft_regs
*regs
,
420 const struct nft_pktinfo
*pkt
)
422 const struct nft_meta
*meta
= nft_expr_priv(expr
);
423 struct sk_buff
*skb
= pkt
->skb
;
424 u32
*sreg
= ®s
->data
[meta
->sreg
];
432 case NFT_META_PRIORITY
:
433 skb
->priority
= value
;
435 case NFT_META_PKTTYPE
:
436 value8
= nft_reg_load8(sreg
);
438 if (skb
->pkt_type
!= value8
&&
439 skb_pkt_type_ok(value8
) &&
440 skb_pkt_type_ok(skb
->pkt_type
))
441 skb
->pkt_type
= value8
;
443 case NFT_META_NFTRACE
:
444 value8
= nft_reg_load8(sreg
);
446 skb
->nf_trace
= !!value8
;
448 #ifdef CONFIG_NETWORK_SECMARK
449 case NFT_META_SECMARK
:
450 skb
->secmark
= value
;
457 EXPORT_SYMBOL_GPL(nft_meta_set_eval
);
459 const struct nla_policy nft_meta_policy
[NFTA_META_MAX
+ 1] = {
460 [NFTA_META_DREG
] = { .type
= NLA_U32
},
461 [NFTA_META_KEY
] = NLA_POLICY_MAX(NLA_BE32
, 255),
462 [NFTA_META_SREG
] = { .type
= NLA_U32
},
464 EXPORT_SYMBOL_GPL(nft_meta_policy
);
466 int nft_meta_get_init(const struct nft_ctx
*ctx
,
467 const struct nft_expr
*expr
,
468 const struct nlattr
* const tb
[])
470 struct nft_meta
*priv
= nft_expr_priv(expr
);
473 priv
->key
= ntohl(nla_get_be32(tb
[NFTA_META_KEY
]));
475 case NFT_META_PROTOCOL
:
476 case NFT_META_IIFTYPE
:
477 case NFT_META_OIFTYPE
:
480 case NFT_META_NFPROTO
:
481 case NFT_META_L4PROTO
:
483 case NFT_META_PRIORITY
:
490 #ifdef CONFIG_IP_ROUTE_CLASSID
491 case NFT_META_RTCLASSID
:
493 #ifdef CONFIG_NETWORK_SECMARK
494 case NFT_META_SECMARK
:
496 case NFT_META_PKTTYPE
:
498 case NFT_META_IIFGROUP
:
499 case NFT_META_OIFGROUP
:
500 #ifdef CONFIG_CGROUP_NET_CLASSID
501 case NFT_META_CGROUP
:
505 case NFT_META_IIFNAME
:
506 case NFT_META_OIFNAME
:
507 case NFT_META_IIFKIND
:
508 case NFT_META_OIFKIND
:
509 case NFT_META_SDIFNAME
:
512 case NFT_META_PRANDOM
:
516 case NFT_META_SECPATH
:
520 case NFT_META_TIME_NS
:
523 case NFT_META_TIME_DAY
:
526 case NFT_META_TIME_HOUR
:
534 return nft_parse_register_store(ctx
, tb
[NFTA_META_DREG
], &priv
->dreg
,
535 NULL
, NFT_DATA_VALUE
, len
);
537 EXPORT_SYMBOL_GPL(nft_meta_get_init
);
539 static int nft_meta_get_validate_sdif(const struct nft_ctx
*ctx
)
543 switch (ctx
->family
) {
547 hooks
= (1 << NF_INET_LOCAL_IN
) |
548 (1 << NF_INET_FORWARD
);
554 return nft_chain_validate_hooks(ctx
->chain
, hooks
);
557 static int nft_meta_get_validate_xfrm(const struct nft_ctx
*ctx
)
562 switch (ctx
->family
) {
564 hooks
= 1 << NF_NETDEV_INGRESS
;
569 hooks
= (1 << NF_INET_PRE_ROUTING
) |
570 (1 << NF_INET_LOCAL_IN
) |
571 (1 << NF_INET_FORWARD
);
577 return nft_chain_validate_hooks(ctx
->chain
, hooks
);
583 static int nft_meta_get_validate(const struct nft_ctx
*ctx
,
584 const struct nft_expr
*expr
)
586 const struct nft_meta
*priv
= nft_expr_priv(expr
);
589 case NFT_META_SECPATH
:
590 return nft_meta_get_validate_xfrm(ctx
);
592 case NFT_META_SDIFNAME
:
593 return nft_meta_get_validate_sdif(ctx
);
601 int nft_meta_set_validate(const struct nft_ctx
*ctx
,
602 const struct nft_expr
*expr
)
604 struct nft_meta
*priv
= nft_expr_priv(expr
);
607 if (priv
->key
!= NFT_META_PKTTYPE
)
610 switch (ctx
->family
) {
612 hooks
= 1 << NF_BR_PRE_ROUTING
;
615 hooks
= 1 << NF_NETDEV_INGRESS
;
620 hooks
= 1 << NF_INET_PRE_ROUTING
;
626 return nft_chain_validate_hooks(ctx
->chain
, hooks
);
628 EXPORT_SYMBOL_GPL(nft_meta_set_validate
);
630 int nft_meta_set_init(const struct nft_ctx
*ctx
,
631 const struct nft_expr
*expr
,
632 const struct nlattr
* const tb
[])
634 struct nft_meta
*priv
= nft_expr_priv(expr
);
638 priv
->key
= ntohl(nla_get_be32(tb
[NFTA_META_KEY
]));
641 case NFT_META_PRIORITY
:
642 #ifdef CONFIG_NETWORK_SECMARK
643 case NFT_META_SECMARK
:
647 case NFT_META_NFTRACE
:
650 case NFT_META_PKTTYPE
:
658 err
= nft_parse_register_load(ctx
, tb
[NFTA_META_SREG
], &priv
->sreg
, len
);
662 if (priv
->key
== NFT_META_NFTRACE
)
663 static_branch_inc(&nft_trace_enabled
);
667 EXPORT_SYMBOL_GPL(nft_meta_set_init
);
669 int nft_meta_get_dump(struct sk_buff
*skb
,
670 const struct nft_expr
*expr
, bool reset
)
672 const struct nft_meta
*priv
= nft_expr_priv(expr
);
674 if (nla_put_be32(skb
, NFTA_META_KEY
, htonl(priv
->key
)))
675 goto nla_put_failure
;
676 if (nft_dump_register(skb
, NFTA_META_DREG
, priv
->dreg
))
677 goto nla_put_failure
;
683 EXPORT_SYMBOL_GPL(nft_meta_get_dump
);
685 int nft_meta_set_dump(struct sk_buff
*skb
,
686 const struct nft_expr
*expr
, bool reset
)
688 const struct nft_meta
*priv
= nft_expr_priv(expr
);
690 if (nla_put_be32(skb
, NFTA_META_KEY
, htonl(priv
->key
)))
691 goto nla_put_failure
;
692 if (nft_dump_register(skb
, NFTA_META_SREG
, priv
->sreg
))
693 goto nla_put_failure
;
700 EXPORT_SYMBOL_GPL(nft_meta_set_dump
);
702 void nft_meta_set_destroy(const struct nft_ctx
*ctx
,
703 const struct nft_expr
*expr
)
705 const struct nft_meta
*priv
= nft_expr_priv(expr
);
707 if (priv
->key
== NFT_META_NFTRACE
)
708 static_branch_dec(&nft_trace_enabled
);
710 EXPORT_SYMBOL_GPL(nft_meta_set_destroy
);
712 static int nft_meta_get_offload(struct nft_offload_ctx
*ctx
,
713 struct nft_flow_rule
*flow
,
714 const struct nft_expr
*expr
)
716 const struct nft_meta
*priv
= nft_expr_priv(expr
);
717 struct nft_offload_reg
*reg
= &ctx
->regs
[priv
->dreg
];
720 case NFT_META_PROTOCOL
:
721 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC
, basic
, n_proto
,
723 nft_offload_set_dependency(ctx
, NFT_OFFLOAD_DEP_NETWORK
);
725 case NFT_META_L4PROTO
:
726 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_BASIC
, basic
, ip_proto
,
728 nft_offload_set_dependency(ctx
, NFT_OFFLOAD_DEP_TRANSPORT
);
731 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META
, meta
,
732 ingress_ifindex
, sizeof(__u32
), reg
);
734 case NFT_META_IIFTYPE
:
735 NFT_OFFLOAD_MATCH_EXACT(FLOW_DISSECTOR_KEY_META
, meta
,
736 ingress_iftype
, sizeof(__u16
), reg
);
745 bool nft_meta_get_reduce(struct nft_regs_track
*track
,
746 const struct nft_expr
*expr
)
748 const struct nft_meta
*priv
= nft_expr_priv(expr
);
749 const struct nft_meta
*meta
;
751 if (!nft_reg_track_cmp(track
, expr
, priv
->dreg
)) {
752 nft_reg_track_update(track
, expr
, priv
->dreg
, priv
->len
);
756 meta
= nft_expr_priv(track
->regs
[priv
->dreg
].selector
);
757 if (priv
->key
!= meta
->key
||
758 priv
->dreg
!= meta
->dreg
) {
759 nft_reg_track_update(track
, expr
, priv
->dreg
, priv
->len
);
763 if (!track
->regs
[priv
->dreg
].bitwise
)
766 return nft_expr_reduce_bitwise(track
, expr
);
768 EXPORT_SYMBOL_GPL(nft_meta_get_reduce
);
770 static const struct nft_expr_ops nft_meta_get_ops
= {
771 .type
= &nft_meta_type
,
772 .size
= NFT_EXPR_SIZE(sizeof(struct nft_meta
)),
773 .eval
= nft_meta_get_eval
,
774 .init
= nft_meta_get_init
,
775 .dump
= nft_meta_get_dump
,
776 .reduce
= nft_meta_get_reduce
,
777 .validate
= nft_meta_get_validate
,
778 .offload
= nft_meta_get_offload
,
781 static bool nft_meta_set_reduce(struct nft_regs_track
*track
,
782 const struct nft_expr
*expr
)
786 for (i
= 0; i
< NFT_REG32_NUM
; i
++) {
787 if (!track
->regs
[i
].selector
)
790 if (track
->regs
[i
].selector
->ops
!= &nft_meta_get_ops
)
793 __nft_reg_track_cancel(track
, i
);
799 static const struct nft_expr_ops nft_meta_set_ops
= {
800 .type
= &nft_meta_type
,
801 .size
= NFT_EXPR_SIZE(sizeof(struct nft_meta
)),
802 .eval
= nft_meta_set_eval
,
803 .init
= nft_meta_set_init
,
804 .destroy
= nft_meta_set_destroy
,
805 .dump
= nft_meta_set_dump
,
806 .reduce
= nft_meta_set_reduce
,
807 .validate
= nft_meta_set_validate
,
810 static const struct nft_expr_ops
*
811 nft_meta_select_ops(const struct nft_ctx
*ctx
,
812 const struct nlattr
* const tb
[])
814 if (tb
[NFTA_META_KEY
] == NULL
)
815 return ERR_PTR(-EINVAL
);
817 if (tb
[NFTA_META_DREG
] && tb
[NFTA_META_SREG
])
818 return ERR_PTR(-EINVAL
);
820 #if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE) && IS_MODULE(CONFIG_NFT_BRIDGE_META)
821 if (ctx
->family
== NFPROTO_BRIDGE
)
822 return ERR_PTR(-EAGAIN
);
824 if (tb
[NFTA_META_DREG
])
825 return &nft_meta_get_ops
;
827 if (tb
[NFTA_META_SREG
])
828 return &nft_meta_set_ops
;
830 return ERR_PTR(-EINVAL
);
833 static int nft_meta_inner_init(const struct nft_ctx
*ctx
,
834 const struct nft_expr
*expr
,
835 const struct nlattr
* const tb
[])
837 struct nft_meta
*priv
= nft_expr_priv(expr
);
840 if (!tb
[NFTA_META_KEY
] || !tb
[NFTA_META_DREG
])
843 priv
->key
= ntohl(nla_get_be32(tb
[NFTA_META_KEY
]));
845 case NFT_META_PROTOCOL
:
848 case NFT_META_L4PROTO
:
856 return nft_parse_register_store(ctx
, tb
[NFTA_META_DREG
], &priv
->dreg
,
857 NULL
, NFT_DATA_VALUE
, len
);
860 void nft_meta_inner_eval(const struct nft_expr
*expr
,
861 struct nft_regs
*regs
,
862 const struct nft_pktinfo
*pkt
,
863 struct nft_inner_tun_ctx
*tun_ctx
)
865 const struct nft_meta
*priv
= nft_expr_priv(expr
);
866 u32
*dest
= ®s
->data
[priv
->dreg
];
869 case NFT_META_PROTOCOL
:
870 nft_reg_store16(dest
, (__force u16
)tun_ctx
->llproto
);
872 case NFT_META_L4PROTO
:
873 if (!(tun_ctx
->flags
& NFT_PAYLOAD_CTX_INNER_TH
))
876 nft_reg_store8(dest
, tun_ctx
->l4proto
);
885 regs
->verdict
.code
= NFT_BREAK
;
887 EXPORT_SYMBOL_GPL(nft_meta_inner_eval
);
889 static const struct nft_expr_ops nft_meta_inner_ops
= {
890 .type
= &nft_meta_type
,
891 .size
= NFT_EXPR_SIZE(sizeof(struct nft_meta
)),
892 .init
= nft_meta_inner_init
,
893 .dump
= nft_meta_get_dump
,
894 /* direct call to nft_meta_inner_eval(). */
897 struct nft_expr_type nft_meta_type __read_mostly
= {
899 .select_ops
= nft_meta_select_ops
,
900 .inner_ops
= &nft_meta_inner_ops
,
901 .policy
= nft_meta_policy
,
902 .maxattr
= NFTA_META_MAX
,
903 .owner
= THIS_MODULE
,
906 #ifdef CONFIG_NETWORK_SECMARK
912 static const struct nla_policy nft_secmark_policy
[NFTA_SECMARK_MAX
+ 1] = {
913 [NFTA_SECMARK_CTX
] = { .type
= NLA_STRING
, .len
= NFT_SECMARK_CTX_MAXLEN
},
916 static int nft_secmark_compute_secid(struct nft_secmark
*priv
)
921 err
= security_secctx_to_secid(priv
->ctx
, strlen(priv
->ctx
), &tmp_secid
);
928 err
= security_secmark_relabel_packet(tmp_secid
);
932 priv
->secid
= tmp_secid
;
936 static void nft_secmark_obj_eval(struct nft_object
*obj
, struct nft_regs
*regs
,
937 const struct nft_pktinfo
*pkt
)
939 const struct nft_secmark
*priv
= nft_obj_data(obj
);
940 struct sk_buff
*skb
= pkt
->skb
;
942 skb
->secmark
= priv
->secid
;
945 static int nft_secmark_obj_init(const struct nft_ctx
*ctx
,
946 const struct nlattr
* const tb
[],
947 struct nft_object
*obj
)
949 struct nft_secmark
*priv
= nft_obj_data(obj
);
952 if (tb
[NFTA_SECMARK_CTX
] == NULL
)
955 priv
->ctx
= nla_strdup(tb
[NFTA_SECMARK_CTX
], GFP_KERNEL_ACCOUNT
);
959 err
= nft_secmark_compute_secid(priv
);
965 security_secmark_refcount_inc();
970 static int nft_secmark_obj_dump(struct sk_buff
*skb
, struct nft_object
*obj
,
973 struct nft_secmark
*priv
= nft_obj_data(obj
);
976 if (nla_put_string(skb
, NFTA_SECMARK_CTX
, priv
->ctx
))
980 err
= nft_secmark_compute_secid(priv
);
988 static void nft_secmark_obj_destroy(const struct nft_ctx
*ctx
, struct nft_object
*obj
)
990 struct nft_secmark
*priv
= nft_obj_data(obj
);
992 security_secmark_refcount_dec();
997 static const struct nft_object_ops nft_secmark_obj_ops
= {
998 .type
= &nft_secmark_obj_type
,
999 .size
= sizeof(struct nft_secmark
),
1000 .init
= nft_secmark_obj_init
,
1001 .eval
= nft_secmark_obj_eval
,
1002 .dump
= nft_secmark_obj_dump
,
1003 .destroy
= nft_secmark_obj_destroy
,
1005 struct nft_object_type nft_secmark_obj_type __read_mostly
= {
1006 .type
= NFT_OBJECT_SECMARK
,
1007 .ops
= &nft_secmark_obj_ops
,
1008 .maxattr
= NFTA_SECMARK_MAX
,
1009 .policy
= nft_secmark_policy
,
1010 .owner
= THIS_MODULE
,
1012 #endif /* CONFIG_NETWORK_SECMARK */