1 // SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB
3 * net/sched/act_ct.c Connection Tracking action
5 * Authors: Paul Blakey <paulb@mellanox.com>
6 * Yossi Kuperman <yossiku@mellanox.com>
7 * Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
10 #include <linux/module.h>
11 #include <linux/init.h>
12 #include <linux/kernel.h>
13 #include <linux/skbuff.h>
14 #include <linux/rtnetlink.h>
15 #include <linux/pkt_cls.h>
17 #include <linux/ipv6.h>
18 #include <linux/rhashtable.h>
19 #include <net/netlink.h>
20 #include <net/pkt_sched.h>
21 #include <net/pkt_cls.h>
22 #include <net/act_api.h>
24 #include <net/ipv6_frag.h>
25 #include <uapi/linux/tc_act/tc_ct.h>
26 #include <net/tc_act/tc_ct.h>
28 #include <net/netfilter/nf_flow_table.h>
29 #include <net/netfilter/nf_conntrack.h>
30 #include <net/netfilter/nf_conntrack_core.h>
31 #include <net/netfilter/nf_conntrack_zones.h>
32 #include <net/netfilter/nf_conntrack_helper.h>
33 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
34 #include <uapi/linux/netfilter/nf_nat.h>
36 static struct workqueue_struct
*act_ct_wq
;
37 static struct rhashtable zones_ht
;
38 static DEFINE_MUTEX(zones_mutex
);
40 struct tcf_ct_flow_table
{
41 struct rhash_head node
; /* In zones tables */
43 struct rcu_work rwork
;
44 struct nf_flowtable nf_ft
;
51 static const struct rhashtable_params zones_params
= {
52 .head_offset
= offsetof(struct tcf_ct_flow_table
, node
),
53 .key_offset
= offsetof(struct tcf_ct_flow_table
, zone
),
54 .key_len
= sizeof_field(struct tcf_ct_flow_table
, zone
),
55 .automatic_shrinking
= true,
58 static struct flow_action_entry
*
59 tcf_ct_flow_table_flow_action_get_next(struct flow_action
*flow_action
)
61 int i
= flow_action
->num_entries
++;
63 return &flow_action
->entries
[i
];
66 static void tcf_ct_add_mangle_action(struct flow_action
*action
,
67 enum flow_action_mangle_base htype
,
72 struct flow_action_entry
*entry
;
74 entry
= tcf_ct_flow_table_flow_action_get_next(action
);
75 entry
->id
= FLOW_ACTION_MANGLE
;
76 entry
->mangle
.htype
= htype
;
77 entry
->mangle
.mask
= ~mask
;
78 entry
->mangle
.offset
= offset
;
79 entry
->mangle
.val
= val
;
82 /* The following nat helper functions check if the inverted reverse tuple
83 * (target) is different then the current dir tuple - meaning nat for ports
84 * and/or ip is needed, and add the relevant mangle actions.
87 tcf_ct_flow_table_add_action_nat_ipv4(const struct nf_conntrack_tuple
*tuple
,
88 struct nf_conntrack_tuple target
,
89 struct flow_action
*action
)
91 if (memcmp(&target
.src
.u3
, &tuple
->src
.u3
, sizeof(target
.src
.u3
)))
92 tcf_ct_add_mangle_action(action
, FLOW_ACT_MANGLE_HDR_TYPE_IP4
,
93 offsetof(struct iphdr
, saddr
),
95 be32_to_cpu(target
.src
.u3
.ip
));
96 if (memcmp(&target
.dst
.u3
, &tuple
->dst
.u3
, sizeof(target
.dst
.u3
)))
97 tcf_ct_add_mangle_action(action
, FLOW_ACT_MANGLE_HDR_TYPE_IP4
,
98 offsetof(struct iphdr
, daddr
),
100 be32_to_cpu(target
.dst
.u3
.ip
));
104 tcf_ct_add_ipv6_addr_mangle_action(struct flow_action
*action
,
105 union nf_inet_addr
*addr
,
110 for (i
= 0; i
< sizeof(struct in6_addr
) / sizeof(u32
); i
++)
111 tcf_ct_add_mangle_action(action
, FLOW_ACT_MANGLE_HDR_TYPE_IP6
,
112 i
* sizeof(u32
) + offset
,
113 0xFFFFFFFF, be32_to_cpu(addr
->ip6
[i
]));
117 tcf_ct_flow_table_add_action_nat_ipv6(const struct nf_conntrack_tuple
*tuple
,
118 struct nf_conntrack_tuple target
,
119 struct flow_action
*action
)
121 if (memcmp(&target
.src
.u3
, &tuple
->src
.u3
, sizeof(target
.src
.u3
)))
122 tcf_ct_add_ipv6_addr_mangle_action(action
, &target
.src
.u3
,
123 offsetof(struct ipv6hdr
,
125 if (memcmp(&target
.dst
.u3
, &tuple
->dst
.u3
, sizeof(target
.dst
.u3
)))
126 tcf_ct_add_ipv6_addr_mangle_action(action
, &target
.dst
.u3
,
127 offsetof(struct ipv6hdr
,
132 tcf_ct_flow_table_add_action_nat_tcp(const struct nf_conntrack_tuple
*tuple
,
133 struct nf_conntrack_tuple target
,
134 struct flow_action
*action
)
136 __be16 target_src
= target
.src
.u
.tcp
.port
;
137 __be16 target_dst
= target
.dst
.u
.tcp
.port
;
139 if (target_src
!= tuple
->src
.u
.tcp
.port
)
140 tcf_ct_add_mangle_action(action
, FLOW_ACT_MANGLE_HDR_TYPE_TCP
,
141 offsetof(struct tcphdr
, source
),
142 0xFFFF, be16_to_cpu(target_src
));
143 if (target_dst
!= tuple
->dst
.u
.tcp
.port
)
144 tcf_ct_add_mangle_action(action
, FLOW_ACT_MANGLE_HDR_TYPE_TCP
,
145 offsetof(struct tcphdr
, dest
),
146 0xFFFF, be16_to_cpu(target_dst
));
150 tcf_ct_flow_table_add_action_nat_udp(const struct nf_conntrack_tuple
*tuple
,
151 struct nf_conntrack_tuple target
,
152 struct flow_action
*action
)
154 __be16 target_src
= target
.src
.u
.udp
.port
;
155 __be16 target_dst
= target
.dst
.u
.udp
.port
;
157 if (target_src
!= tuple
->src
.u
.udp
.port
)
158 tcf_ct_add_mangle_action(action
, FLOW_ACT_MANGLE_HDR_TYPE_TCP
,
159 offsetof(struct udphdr
, source
),
160 0xFFFF, be16_to_cpu(target_src
));
161 if (target_dst
!= tuple
->dst
.u
.udp
.port
)
162 tcf_ct_add_mangle_action(action
, FLOW_ACT_MANGLE_HDR_TYPE_TCP
,
163 offsetof(struct udphdr
, dest
),
164 0xFFFF, be16_to_cpu(target_dst
));
167 static void tcf_ct_flow_table_add_action_meta(struct nf_conn
*ct
,
168 enum ip_conntrack_dir dir
,
169 struct flow_action
*action
)
171 struct nf_conn_labels
*ct_labels
;
172 struct flow_action_entry
*entry
;
173 enum ip_conntrack_info ctinfo
;
176 entry
= tcf_ct_flow_table_flow_action_get_next(action
);
177 entry
->id
= FLOW_ACTION_CT_METADATA
;
178 #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
179 entry
->ct_metadata
.mark
= ct
->mark
;
181 ctinfo
= dir
== IP_CT_DIR_ORIGINAL
? IP_CT_ESTABLISHED
:
182 IP_CT_ESTABLISHED_REPLY
;
183 /* aligns with the CT reference on the SKB nf_ct_set */
184 entry
->ct_metadata
.cookie
= (unsigned long)ct
| ctinfo
;
186 act_ct_labels
= entry
->ct_metadata
.labels
;
187 ct_labels
= nf_ct_labels_find(ct
);
189 memcpy(act_ct_labels
, ct_labels
->bits
, NF_CT_LABELS_MAX_SIZE
);
191 memset(act_ct_labels
, 0, NF_CT_LABELS_MAX_SIZE
);
194 static int tcf_ct_flow_table_add_action_nat(struct net
*net
,
196 enum ip_conntrack_dir dir
,
197 struct flow_action
*action
)
199 const struct nf_conntrack_tuple
*tuple
= &ct
->tuplehash
[dir
].tuple
;
200 struct nf_conntrack_tuple target
;
202 nf_ct_invert_tuple(&target
, &ct
->tuplehash
[!dir
].tuple
);
204 switch (tuple
->src
.l3num
) {
206 tcf_ct_flow_table_add_action_nat_ipv4(tuple
, target
,
210 tcf_ct_flow_table_add_action_nat_ipv6(tuple
, target
,
217 switch (nf_ct_protonum(ct
)) {
219 tcf_ct_flow_table_add_action_nat_tcp(tuple
, target
, action
);
222 tcf_ct_flow_table_add_action_nat_udp(tuple
, target
, action
);
231 static int tcf_ct_flow_table_fill_actions(struct net
*net
,
232 const struct flow_offload
*flow
,
233 enum flow_offload_tuple_dir tdir
,
234 struct nf_flow_rule
*flow_rule
)
236 struct flow_action
*action
= &flow_rule
->rule
->action
;
237 int num_entries
= action
->num_entries
;
238 struct nf_conn
*ct
= flow
->ct
;
239 enum ip_conntrack_dir dir
;
243 case FLOW_OFFLOAD_DIR_ORIGINAL
:
244 dir
= IP_CT_DIR_ORIGINAL
;
246 case FLOW_OFFLOAD_DIR_REPLY
:
247 dir
= IP_CT_DIR_REPLY
;
253 err
= tcf_ct_flow_table_add_action_nat(net
, ct
, dir
, action
);
257 tcf_ct_flow_table_add_action_meta(ct
, dir
, action
);
261 /* Clear filled actions */
262 for (i
= num_entries
; i
< action
->num_entries
; i
++)
263 memset(&action
->entries
[i
], 0, sizeof(action
->entries
[i
]));
264 action
->num_entries
= num_entries
;
269 static struct nf_flowtable_type flowtable_ct
= {
270 .action
= tcf_ct_flow_table_fill_actions
,
271 .owner
= THIS_MODULE
,
274 static int tcf_ct_flow_table_get(struct tcf_ct_params
*params
)
276 struct tcf_ct_flow_table
*ct_ft
;
279 mutex_lock(&zones_mutex
);
280 ct_ft
= rhashtable_lookup_fast(&zones_ht
, ¶ms
->zone
, zones_params
);
281 if (ct_ft
&& refcount_inc_not_zero(&ct_ft
->ref
))
284 ct_ft
= kzalloc(sizeof(*ct_ft
), GFP_KERNEL
);
287 refcount_set(&ct_ft
->ref
, 1);
289 ct_ft
->zone
= params
->zone
;
290 err
= rhashtable_insert_fast(&zones_ht
, &ct_ft
->node
, zones_params
);
294 ct_ft
->nf_ft
.type
= &flowtable_ct
;
295 ct_ft
->nf_ft
.flags
|= NF_FLOWTABLE_HW_OFFLOAD
;
296 err
= nf_flow_table_init(&ct_ft
->nf_ft
);
300 __module_get(THIS_MODULE
);
302 params
->ct_ft
= ct_ft
;
303 params
->nf_ft
= &ct_ft
->nf_ft
;
304 mutex_unlock(&zones_mutex
);
309 rhashtable_remove_fast(&zones_ht
, &ct_ft
->node
, zones_params
);
313 mutex_unlock(&zones_mutex
);
317 static void tcf_ct_flow_table_cleanup_work(struct work_struct
*work
)
319 struct tcf_ct_flow_table
*ct_ft
;
321 ct_ft
= container_of(to_rcu_work(work
), struct tcf_ct_flow_table
,
323 nf_flow_table_free(&ct_ft
->nf_ft
);
326 module_put(THIS_MODULE
);
329 static void tcf_ct_flow_table_put(struct tcf_ct_params
*params
)
331 struct tcf_ct_flow_table
*ct_ft
= params
->ct_ft
;
333 if (refcount_dec_and_test(¶ms
->ct_ft
->ref
)) {
334 rhashtable_remove_fast(&zones_ht
, &ct_ft
->node
, zones_params
);
335 INIT_RCU_WORK(&ct_ft
->rwork
, tcf_ct_flow_table_cleanup_work
);
336 queue_rcu_work(act_ct_wq
, &ct_ft
->rwork
);
340 static void tcf_ct_flow_table_add(struct tcf_ct_flow_table
*ct_ft
,
344 struct flow_offload
*entry
;
347 if (test_and_set_bit(IPS_OFFLOAD_BIT
, &ct
->status
))
350 entry
= flow_offload_alloc(ct
);
357 ct
->proto
.tcp
.seen
[0].flags
|= IP_CT_TCP_FLAG_BE_LIBERAL
;
358 ct
->proto
.tcp
.seen
[1].flags
|= IP_CT_TCP_FLAG_BE_LIBERAL
;
361 err
= flow_offload_add(&ct_ft
->nf_ft
, entry
);
368 flow_offload_free(entry
);
370 clear_bit(IPS_OFFLOAD_BIT
, &ct
->status
);
373 static void tcf_ct_flow_table_process_conn(struct tcf_ct_flow_table
*ct_ft
,
375 enum ip_conntrack_info ctinfo
)
379 if (ctinfo
!= IP_CT_ESTABLISHED
&& ctinfo
!= IP_CT_ESTABLISHED_REPLY
)
382 switch (nf_ct_protonum(ct
)) {
385 if (ct
->proto
.tcp
.state
!= TCP_CONNTRACK_ESTABLISHED
)
394 if (nf_ct_ext_exist(ct
, NF_CT_EXT_HELPER
) ||
395 ct
->status
& IPS_SEQ_ADJUST
)
398 tcf_ct_flow_table_add(ct_ft
, ct
, tcp
);
402 tcf_ct_flow_table_fill_tuple_ipv4(struct sk_buff
*skb
,
403 struct flow_offload_tuple
*tuple
,
404 struct tcphdr
**tcph
)
406 struct flow_ports
*ports
;
410 if (!pskb_network_may_pull(skb
, sizeof(*iph
)))
414 thoff
= iph
->ihl
* 4;
416 if (ip_is_fragment(iph
) ||
417 unlikely(thoff
!= sizeof(struct iphdr
)))
420 if (iph
->protocol
!= IPPROTO_TCP
&&
421 iph
->protocol
!= IPPROTO_UDP
)
427 if (!pskb_network_may_pull(skb
, iph
->protocol
== IPPROTO_TCP
?
428 thoff
+ sizeof(struct tcphdr
) :
429 thoff
+ sizeof(*ports
)))
433 if (iph
->protocol
== IPPROTO_TCP
)
434 *tcph
= (void *)(skb_network_header(skb
) + thoff
);
436 ports
= (struct flow_ports
*)(skb_network_header(skb
) + thoff
);
437 tuple
->src_v4
.s_addr
= iph
->saddr
;
438 tuple
->dst_v4
.s_addr
= iph
->daddr
;
439 tuple
->src_port
= ports
->source
;
440 tuple
->dst_port
= ports
->dest
;
441 tuple
->l3proto
= AF_INET
;
442 tuple
->l4proto
= iph
->protocol
;
448 tcf_ct_flow_table_fill_tuple_ipv6(struct sk_buff
*skb
,
449 struct flow_offload_tuple
*tuple
,
450 struct tcphdr
**tcph
)
452 struct flow_ports
*ports
;
453 struct ipv6hdr
*ip6h
;
456 if (!pskb_network_may_pull(skb
, sizeof(*ip6h
)))
459 ip6h
= ipv6_hdr(skb
);
461 if (ip6h
->nexthdr
!= IPPROTO_TCP
&&
462 ip6h
->nexthdr
!= IPPROTO_UDP
)
465 if (ip6h
->hop_limit
<= 1)
468 thoff
= sizeof(*ip6h
);
469 if (!pskb_network_may_pull(skb
, ip6h
->nexthdr
== IPPROTO_TCP
?
470 thoff
+ sizeof(struct tcphdr
) :
471 thoff
+ sizeof(*ports
)))
474 ip6h
= ipv6_hdr(skb
);
475 if (ip6h
->nexthdr
== IPPROTO_TCP
)
476 *tcph
= (void *)(skb_network_header(skb
) + thoff
);
478 ports
= (struct flow_ports
*)(skb_network_header(skb
) + thoff
);
479 tuple
->src_v6
= ip6h
->saddr
;
480 tuple
->dst_v6
= ip6h
->daddr
;
481 tuple
->src_port
= ports
->source
;
482 tuple
->dst_port
= ports
->dest
;
483 tuple
->l3proto
= AF_INET6
;
484 tuple
->l4proto
= ip6h
->nexthdr
;
489 static bool tcf_ct_flow_table_lookup(struct tcf_ct_params
*p
,
493 struct nf_flowtable
*nf_ft
= &p
->ct_ft
->nf_ft
;
494 struct flow_offload_tuple_rhash
*tuplehash
;
495 struct flow_offload_tuple tuple
= {};
496 enum ip_conntrack_info ctinfo
;
497 struct tcphdr
*tcph
= NULL
;
498 struct flow_offload
*flow
;
502 /* Previously seen or loopback */
503 ct
= nf_ct_get(skb
, &ctinfo
);
504 if ((ct
&& !nf_ct_is_template(ct
)) || ctinfo
== IP_CT_UNTRACKED
)
509 if (!tcf_ct_flow_table_fill_tuple_ipv4(skb
, &tuple
, &tcph
))
513 if (!tcf_ct_flow_table_fill_tuple_ipv6(skb
, &tuple
, &tcph
))
520 tuplehash
= flow_offload_lookup(nf_ft
, &tuple
);
524 dir
= tuplehash
->tuple
.dir
;
525 flow
= container_of(tuplehash
, struct flow_offload
, tuplehash
[dir
]);
528 if (tcph
&& (unlikely(tcph
->fin
|| tcph
->rst
))) {
529 flow_offload_teardown(flow
);
533 ctinfo
= dir
== FLOW_OFFLOAD_DIR_ORIGINAL
? IP_CT_ESTABLISHED
:
534 IP_CT_ESTABLISHED_REPLY
;
536 flow_offload_refresh(nf_ft
, flow
);
537 nf_conntrack_get(&ct
->ct_general
);
538 nf_ct_set(skb
, ct
, ctinfo
);
543 static int tcf_ct_flow_tables_init(void)
545 return rhashtable_init(&zones_ht
, &zones_params
);
548 static void tcf_ct_flow_tables_uninit(void)
550 rhashtable_destroy(&zones_ht
);
553 static struct tc_action_ops act_ct_ops
;
554 static unsigned int ct_net_id
;
556 struct tc_ct_action_net
{
557 struct tc_action_net tn
; /* Must be first */
561 /* Determine whether skb->_nfct is equal to the result of conntrack lookup. */
562 static bool tcf_ct_skb_nfct_cached(struct net
*net
, struct sk_buff
*skb
,
563 u16 zone_id
, bool force
)
565 enum ip_conntrack_info ctinfo
;
568 ct
= nf_ct_get(skb
, &ctinfo
);
571 if (!net_eq(net
, read_pnet(&ct
->ct_net
)))
573 if (nf_ct_zone(ct
)->id
!= zone_id
)
576 /* Force conntrack entry direction. */
577 if (force
&& CTINFO2DIR(ctinfo
) != IP_CT_DIR_ORIGINAL
) {
578 if (nf_ct_is_confirmed(ct
))
581 nf_conntrack_put(&ct
->ct_general
);
582 nf_ct_set(skb
, NULL
, IP_CT_UNTRACKED
);
590 /* Trim the skb to the length specified by the IP/IPv6 header,
591 * removing any trailing lower-layer padding. This prepares the skb
592 * for higher-layer processing that assumes skb->len excludes padding
593 * (such as nf_ip_checksum). The caller needs to pull the skb to the
594 * network header, and ensure ip_hdr/ipv6_hdr points to valid data.
596 static int tcf_ct_skb_network_trim(struct sk_buff
*skb
, int family
)
603 len
= ntohs(ip_hdr(skb
)->tot_len
);
606 len
= sizeof(struct ipv6hdr
)
607 + ntohs(ipv6_hdr(skb
)->payload_len
);
613 err
= pskb_trim_rcsum(skb
, len
);
618 static u8
tcf_ct_skb_nf_family(struct sk_buff
*skb
)
620 u8 family
= NFPROTO_UNSPEC
;
622 switch (skb
->protocol
) {
623 case htons(ETH_P_IP
):
624 family
= NFPROTO_IPV4
;
626 case htons(ETH_P_IPV6
):
627 family
= NFPROTO_IPV6
;
636 static int tcf_ct_ipv4_is_fragment(struct sk_buff
*skb
, bool *frag
)
640 len
= skb_network_offset(skb
) + sizeof(struct iphdr
);
641 if (unlikely(skb
->len
< len
))
643 if (unlikely(!pskb_may_pull(skb
, len
)))
646 *frag
= ip_is_fragment(ip_hdr(skb
));
650 static int tcf_ct_ipv6_is_fragment(struct sk_buff
*skb
, bool *frag
)
652 unsigned int flags
= 0, len
, payload_ofs
= 0;
653 unsigned short frag_off
;
656 len
= skb_network_offset(skb
) + sizeof(struct ipv6hdr
);
657 if (unlikely(skb
->len
< len
))
659 if (unlikely(!pskb_may_pull(skb
, len
)))
662 nexthdr
= ipv6_find_hdr(skb
, &payload_ofs
, -1, &frag_off
, &flags
);
663 if (unlikely(nexthdr
< 0))
666 *frag
= flags
& IP6_FH_F_FRAG
;
670 static int tcf_ct_handle_fragments(struct net
*net
, struct sk_buff
*skb
,
673 enum ip_conntrack_info ctinfo
;
678 /* Previously seen (loopback)? Ignore. */
679 ct
= nf_ct_get(skb
, &ctinfo
);
680 if ((ct
&& !nf_ct_is_template(ct
)) || ctinfo
== IP_CT_UNTRACKED
)
683 if (family
== NFPROTO_IPV4
)
684 err
= tcf_ct_ipv4_is_fragment(skb
, &frag
);
686 err
= tcf_ct_ipv6_is_fragment(skb
, &frag
);
692 if (family
== NFPROTO_IPV4
) {
693 enum ip_defrag_users user
= IP_DEFRAG_CONNTRACK_IN
+ zone
;
695 memset(IPCB(skb
), 0, sizeof(struct inet_skb_parm
));
697 err
= ip_defrag(net
, skb
, user
);
699 if (err
&& err
!= -EINPROGRESS
)
701 } else { /* NFPROTO_IPV6 */
702 #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV6)
703 enum ip6_defrag_users user
= IP6_DEFRAG_CONNTRACK_IN
+ zone
;
705 memset(IP6CB(skb
), 0, sizeof(struct inet6_skb_parm
));
706 err
= nf_ct_frag6_gather(net
, skb
, user
);
707 if (err
&& err
!= -EINPROGRESS
)
724 static void tcf_ct_params_free(struct rcu_head
*head
)
726 struct tcf_ct_params
*params
= container_of(head
,
727 struct tcf_ct_params
, rcu
);
729 tcf_ct_flow_table_put(params
);
732 nf_conntrack_put(¶ms
->tmpl
->ct_general
);
736 #if IS_ENABLED(CONFIG_NF_NAT)
737 /* Modelled after nf_nat_ipv[46]_fn().
738 * range is only used for new, uninitialized NAT state.
739 * Returns either NF_ACCEPT or NF_DROP.
741 static int ct_nat_execute(struct sk_buff
*skb
, struct nf_conn
*ct
,
742 enum ip_conntrack_info ctinfo
,
743 const struct nf_nat_range2
*range
,
744 enum nf_nat_manip_type maniptype
)
746 int hooknum
, err
= NF_ACCEPT
;
748 /* See HOOK2MANIP(). */
749 if (maniptype
== NF_NAT_MANIP_SRC
)
750 hooknum
= NF_INET_LOCAL_IN
; /* Source NAT */
752 hooknum
= NF_INET_LOCAL_OUT
; /* Destination NAT */
756 case IP_CT_RELATED_REPLY
:
757 if (skb
->protocol
== htons(ETH_P_IP
) &&
758 ip_hdr(skb
)->protocol
== IPPROTO_ICMP
) {
759 if (!nf_nat_icmp_reply_translation(skb
, ct
, ctinfo
,
763 } else if (IS_ENABLED(CONFIG_IPV6
) &&
764 skb
->protocol
== htons(ETH_P_IPV6
)) {
766 u8 nexthdr
= ipv6_hdr(skb
)->nexthdr
;
767 int hdrlen
= ipv6_skip_exthdr(skb
,
768 sizeof(struct ipv6hdr
),
769 &nexthdr
, &frag_off
);
771 if (hdrlen
>= 0 && nexthdr
== IPPROTO_ICMPV6
) {
772 if (!nf_nat_icmpv6_reply_translation(skb
, ct
,
780 /* Non-ICMP, fall thru to initialize if needed. */
783 /* Seen it before? This can happen for loopback, retrans,
786 if (!nf_nat_initialized(ct
, maniptype
)) {
787 /* Initialize according to the NAT action. */
788 err
= (range
&& range
->flags
& NF_NAT_RANGE_MAP_IPS
)
789 /* Action is set up to establish a new
792 ? nf_nat_setup_info(ct
, range
, maniptype
)
793 : nf_nat_alloc_null_binding(ct
, hooknum
);
794 if (err
!= NF_ACCEPT
)
799 case IP_CT_ESTABLISHED
:
800 case IP_CT_ESTABLISHED_REPLY
:
808 err
= nf_nat_packet(ct
, ctinfo
, hooknum
, skb
);
812 #endif /* CONFIG_NF_NAT */
814 static void tcf_ct_act_set_mark(struct nf_conn
*ct
, u32 mark
, u32 mask
)
816 #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
822 new_mark
= mark
| (ct
->mark
& ~(mask
));
823 if (ct
->mark
!= new_mark
) {
825 if (nf_ct_is_confirmed(ct
))
826 nf_conntrack_event_cache(IPCT_MARK
, ct
);
831 static void tcf_ct_act_set_labels(struct nf_conn
*ct
,
835 #if IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS)
836 size_t labels_sz
= sizeof_field(struct tcf_ct_params
, labels
);
838 if (!memchr_inv(labels_m
, 0, labels_sz
))
841 nf_connlabels_replace(ct
, labels
, labels_m
, 4);
845 static int tcf_ct_act_nat(struct sk_buff
*skb
,
847 enum ip_conntrack_info ctinfo
,
849 struct nf_nat_range2
*range
,
852 #if IS_ENABLED(CONFIG_NF_NAT)
854 enum nf_nat_manip_type maniptype
;
856 if (!(ct_action
& TCA_CT_ACT_NAT
))
859 /* Add NAT extension if not confirmed yet. */
860 if (!nf_ct_is_confirmed(ct
) && !nf_ct_nat_ext_add(ct
))
861 return NF_DROP
; /* Can't NAT. */
863 if (ctinfo
!= IP_CT_NEW
&& (ct
->status
& IPS_NAT_MASK
) &&
864 (ctinfo
!= IP_CT_RELATED
|| commit
)) {
865 /* NAT an established or related connection like before. */
866 if (CTINFO2DIR(ctinfo
) == IP_CT_DIR_REPLY
)
867 /* This is the REPLY direction for a connection
868 * for which NAT was applied in the forward
869 * direction. Do the reverse NAT.
871 maniptype
= ct
->status
& IPS_SRC_NAT
872 ? NF_NAT_MANIP_DST
: NF_NAT_MANIP_SRC
;
874 maniptype
= ct
->status
& IPS_SRC_NAT
875 ? NF_NAT_MANIP_SRC
: NF_NAT_MANIP_DST
;
876 } else if (ct_action
& TCA_CT_ACT_NAT_SRC
) {
877 maniptype
= NF_NAT_MANIP_SRC
;
878 } else if (ct_action
& TCA_CT_ACT_NAT_DST
) {
879 maniptype
= NF_NAT_MANIP_DST
;
884 err
= ct_nat_execute(skb
, ct
, ctinfo
, range
, maniptype
);
885 if (err
== NF_ACCEPT
&&
886 ct
->status
& IPS_SRC_NAT
&& ct
->status
& IPS_DST_NAT
) {
887 if (maniptype
== NF_NAT_MANIP_SRC
)
888 maniptype
= NF_NAT_MANIP_DST
;
890 maniptype
= NF_NAT_MANIP_SRC
;
892 err
= ct_nat_execute(skb
, ct
, ctinfo
, range
, maniptype
);
900 static int tcf_ct_act(struct sk_buff
*skb
, const struct tc_action
*a
,
901 struct tcf_result
*res
)
903 struct net
*net
= dev_net(skb
->dev
);
904 bool cached
, commit
, clear
, force
;
905 enum ip_conntrack_info ctinfo
;
906 struct tcf_ct
*c
= to_ct(a
);
907 struct nf_conn
*tmpl
= NULL
;
908 struct nf_hook_state state
;
909 int nh_ofs
, err
, retval
;
910 struct tcf_ct_params
*p
;
911 bool skip_add
= false;
915 p
= rcu_dereference_bh(c
->params
);
917 retval
= READ_ONCE(c
->tcf_action
);
918 commit
= p
->ct_action
& TCA_CT_ACT_COMMIT
;
919 clear
= p
->ct_action
& TCA_CT_ACT_CLEAR
;
920 force
= p
->ct_action
& TCA_CT_ACT_FORCE
;
924 ct
= nf_ct_get(skb
, &ctinfo
);
926 nf_conntrack_put(&ct
->ct_general
);
927 nf_ct_set(skb
, NULL
, IP_CT_UNTRACKED
);
933 family
= tcf_ct_skb_nf_family(skb
);
934 if (family
== NFPROTO_UNSPEC
)
937 /* The conntrack module expects to be working at L3.
938 * We also try to pull the IPv4/6 header to linear area
940 nh_ofs
= skb_network_offset(skb
);
941 skb_pull_rcsum(skb
, nh_ofs
);
942 err
= tcf_ct_handle_fragments(net
, skb
, family
, p
->zone
);
943 if (err
== -EINPROGRESS
) {
944 retval
= TC_ACT_STOLEN
;
950 err
= tcf_ct_skb_network_trim(skb
, family
);
954 /* If we are recirculating packets to match on ct fields and
955 * committing with a separate ct action, then we don't need to
956 * actually run the packet through conntrack twice unless it's for a
959 cached
= tcf_ct_skb_nfct_cached(net
, skb
, p
->zone
, force
);
961 if (!commit
&& tcf_ct_flow_table_lookup(p
, skb
, family
)) {
966 /* Associate skb with specified zone. */
968 ct
= nf_ct_get(skb
, &ctinfo
);
970 nf_conntrack_put(skb_nfct(skb
));
971 nf_conntrack_get(&tmpl
->ct_general
);
972 nf_ct_set(skb
, tmpl
, IP_CT_NEW
);
975 state
.hook
= NF_INET_PRE_ROUTING
;
978 err
= nf_conntrack_in(skb
, &state
);
979 if (err
!= NF_ACCEPT
)
984 ct
= nf_ct_get(skb
, &ctinfo
);
987 nf_ct_deliver_cached_events(ct
);
989 err
= tcf_ct_act_nat(skb
, ct
, ctinfo
, p
->ct_action
, &p
->range
, commit
);
990 if (err
!= NF_ACCEPT
)
994 tcf_ct_act_set_mark(ct
, p
->mark
, p
->mark_mask
);
995 tcf_ct_act_set_labels(ct
, p
->labels
, p
->labels_mask
);
997 /* This will take care of sending queued events
998 * even if the connection is already confirmed.
1000 nf_conntrack_confirm(skb
);
1001 } else if (!skip_add
) {
1002 tcf_ct_flow_table_process_conn(p
->ct_ft
, ct
, ctinfo
);
1006 skb_push_rcsum(skb
, nh_ofs
);
1009 tcf_action_update_bstats(&c
->common
, skb
);
1013 tcf_action_inc_drop_qstats(&c
->common
);
1017 static const struct nla_policy ct_policy
[TCA_CT_MAX
+ 1] = {
1018 [TCA_CT_ACTION
] = { .type
= NLA_U16
},
1019 [TCA_CT_PARMS
] = { .type
= NLA_EXACT_LEN
, .len
= sizeof(struct tc_ct
) },
1020 [TCA_CT_ZONE
] = { .type
= NLA_U16
},
1021 [TCA_CT_MARK
] = { .type
= NLA_U32
},
1022 [TCA_CT_MARK_MASK
] = { .type
= NLA_U32
},
1023 [TCA_CT_LABELS
] = { .type
= NLA_BINARY
,
1024 .len
= 128 / BITS_PER_BYTE
},
1025 [TCA_CT_LABELS_MASK
] = { .type
= NLA_BINARY
,
1026 .len
= 128 / BITS_PER_BYTE
},
1027 [TCA_CT_NAT_IPV4_MIN
] = { .type
= NLA_U32
},
1028 [TCA_CT_NAT_IPV4_MAX
] = { .type
= NLA_U32
},
1029 [TCA_CT_NAT_IPV6_MIN
] = { .type
= NLA_EXACT_LEN
,
1030 .len
= sizeof(struct in6_addr
) },
1031 [TCA_CT_NAT_IPV6_MAX
] = { .type
= NLA_EXACT_LEN
,
1032 .len
= sizeof(struct in6_addr
) },
1033 [TCA_CT_NAT_PORT_MIN
] = { .type
= NLA_U16
},
1034 [TCA_CT_NAT_PORT_MAX
] = { .type
= NLA_U16
},
1037 static int tcf_ct_fill_params_nat(struct tcf_ct_params
*p
,
1040 struct netlink_ext_ack
*extack
)
1042 struct nf_nat_range2
*range
;
1044 if (!(p
->ct_action
& TCA_CT_ACT_NAT
))
1047 if (!IS_ENABLED(CONFIG_NF_NAT
)) {
1048 NL_SET_ERR_MSG_MOD(extack
, "Netfilter nat isn't enabled in kernel");
1052 if (!(p
->ct_action
& (TCA_CT_ACT_NAT_SRC
| TCA_CT_ACT_NAT_DST
)))
1055 if ((p
->ct_action
& TCA_CT_ACT_NAT_SRC
) &&
1056 (p
->ct_action
& TCA_CT_ACT_NAT_DST
)) {
1057 NL_SET_ERR_MSG_MOD(extack
, "dnat and snat can't be enabled at the same time");
1062 if (tb
[TCA_CT_NAT_IPV4_MIN
]) {
1063 struct nlattr
*max_attr
= tb
[TCA_CT_NAT_IPV4_MAX
];
1065 p
->ipv4_range
= true;
1066 range
->flags
|= NF_NAT_RANGE_MAP_IPS
;
1067 range
->min_addr
.ip
=
1068 nla_get_in_addr(tb
[TCA_CT_NAT_IPV4_MIN
]);
1070 range
->max_addr
.ip
= max_attr
?
1071 nla_get_in_addr(max_attr
) :
1073 } else if (tb
[TCA_CT_NAT_IPV6_MIN
]) {
1074 struct nlattr
*max_attr
= tb
[TCA_CT_NAT_IPV6_MAX
];
1076 p
->ipv4_range
= false;
1077 range
->flags
|= NF_NAT_RANGE_MAP_IPS
;
1078 range
->min_addr
.in6
=
1079 nla_get_in6_addr(tb
[TCA_CT_NAT_IPV6_MIN
]);
1081 range
->max_addr
.in6
= max_attr
?
1082 nla_get_in6_addr(max_attr
) :
1083 range
->min_addr
.in6
;
1086 if (tb
[TCA_CT_NAT_PORT_MIN
]) {
1087 range
->flags
|= NF_NAT_RANGE_PROTO_SPECIFIED
;
1088 range
->min_proto
.all
= nla_get_be16(tb
[TCA_CT_NAT_PORT_MIN
]);
1090 range
->max_proto
.all
= tb
[TCA_CT_NAT_PORT_MAX
] ?
1091 nla_get_be16(tb
[TCA_CT_NAT_PORT_MAX
]) :
1092 range
->min_proto
.all
;
1098 static void tcf_ct_set_key_val(struct nlattr
**tb
,
1099 void *val
, int val_type
,
1100 void *mask
, int mask_type
,
1105 nla_memcpy(val
, tb
[val_type
], len
);
1110 if (mask_type
== TCA_CT_UNSPEC
|| !tb
[mask_type
])
1111 memset(mask
, 0xff, len
);
1113 nla_memcpy(mask
, tb
[mask_type
], len
);
1116 static int tcf_ct_fill_params(struct net
*net
,
1117 struct tcf_ct_params
*p
,
1120 struct netlink_ext_ack
*extack
)
1122 struct tc_ct_action_net
*tn
= net_generic(net
, ct_net_id
);
1123 struct nf_conntrack_zone zone
;
1124 struct nf_conn
*tmpl
;
1127 p
->zone
= NF_CT_DEFAULT_ZONE_ID
;
1129 tcf_ct_set_key_val(tb
,
1130 &p
->ct_action
, TCA_CT_ACTION
,
1131 NULL
, TCA_CT_UNSPEC
,
1132 sizeof(p
->ct_action
));
1134 if (p
->ct_action
& TCA_CT_ACT_CLEAR
)
1137 err
= tcf_ct_fill_params_nat(p
, parm
, tb
, extack
);
1141 if (tb
[TCA_CT_MARK
]) {
1142 if (!IS_ENABLED(CONFIG_NF_CONNTRACK_MARK
)) {
1143 NL_SET_ERR_MSG_MOD(extack
, "Conntrack mark isn't enabled.");
1146 tcf_ct_set_key_val(tb
,
1147 &p
->mark
, TCA_CT_MARK
,
1148 &p
->mark_mask
, TCA_CT_MARK_MASK
,
1152 if (tb
[TCA_CT_LABELS
]) {
1153 if (!IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS
)) {
1154 NL_SET_ERR_MSG_MOD(extack
, "Conntrack labels isn't enabled.");
1159 NL_SET_ERR_MSG_MOD(extack
, "Failed to set connlabel length");
1162 tcf_ct_set_key_val(tb
,
1163 p
->labels
, TCA_CT_LABELS
,
1164 p
->labels_mask
, TCA_CT_LABELS_MASK
,
1168 if (tb
[TCA_CT_ZONE
]) {
1169 if (!IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES
)) {
1170 NL_SET_ERR_MSG_MOD(extack
, "Conntrack zones isn't enabled.");
1174 tcf_ct_set_key_val(tb
,
1175 &p
->zone
, TCA_CT_ZONE
,
1176 NULL
, TCA_CT_UNSPEC
,
1180 if (p
->zone
== NF_CT_DEFAULT_ZONE_ID
)
1183 nf_ct_zone_init(&zone
, p
->zone
, NF_CT_DEFAULT_ZONE_DIR
, 0);
1184 tmpl
= nf_ct_tmpl_alloc(net
, &zone
, GFP_KERNEL
);
1186 NL_SET_ERR_MSG_MOD(extack
, "Failed to allocate conntrack template");
1189 __set_bit(IPS_CONFIRMED_BIT
, &tmpl
->status
);
1190 nf_conntrack_get(&tmpl
->ct_general
);
1196 static int tcf_ct_init(struct net
*net
, struct nlattr
*nla
,
1197 struct nlattr
*est
, struct tc_action
**a
,
1198 int replace
, int bind
, bool rtnl_held
,
1199 struct tcf_proto
*tp
, u32 flags
,
1200 struct netlink_ext_ack
*extack
)
1202 struct tc_action_net
*tn
= net_generic(net
, ct_net_id
);
1203 struct tcf_ct_params
*params
= NULL
;
1204 struct nlattr
*tb
[TCA_CT_MAX
+ 1];
1205 struct tcf_chain
*goto_ch
= NULL
;
1212 NL_SET_ERR_MSG_MOD(extack
, "Ct requires attributes to be passed");
1216 err
= nla_parse_nested(tb
, TCA_CT_MAX
, nla
, ct_policy
, extack
);
1220 if (!tb
[TCA_CT_PARMS
]) {
1221 NL_SET_ERR_MSG_MOD(extack
, "Missing required ct parameters");
1224 parm
= nla_data(tb
[TCA_CT_PARMS
]);
1225 index
= parm
->index
;
1226 err
= tcf_idr_check_alloc(tn
, &index
, a
, bind
);
1231 err
= tcf_idr_create_from_flags(tn
, index
, est
, a
,
1232 &act_ct_ops
, bind
, flags
);
1234 tcf_idr_cleanup(tn
, index
);
1237 res
= ACT_P_CREATED
;
1243 tcf_idr_release(*a
, bind
);
1247 err
= tcf_action_check_ctrlact(parm
->action
, tp
, &goto_ch
, extack
);
1253 params
= kzalloc(sizeof(*params
), GFP_KERNEL
);
1254 if (unlikely(!params
)) {
1259 err
= tcf_ct_fill_params(net
, params
, parm
, tb
, extack
);
1263 err
= tcf_ct_flow_table_get(params
);
1267 spin_lock_bh(&c
->tcf_lock
);
1268 goto_ch
= tcf_action_set_ctrlact(*a
, parm
->action
, goto_ch
);
1269 params
= rcu_replace_pointer(c
->params
, params
,
1270 lockdep_is_held(&c
->tcf_lock
));
1271 spin_unlock_bh(&c
->tcf_lock
);
1274 tcf_chain_put_by_act(goto_ch
);
1276 call_rcu(¶ms
->rcu
, tcf_ct_params_free
);
1277 if (res
== ACT_P_CREATED
)
1278 tcf_idr_insert(tn
, *a
);
1284 tcf_chain_put_by_act(goto_ch
);
1286 tcf_idr_release(*a
, bind
);
1290 static void tcf_ct_cleanup(struct tc_action
*a
)
1292 struct tcf_ct_params
*params
;
1293 struct tcf_ct
*c
= to_ct(a
);
1295 params
= rcu_dereference_protected(c
->params
, 1);
1297 call_rcu(¶ms
->rcu
, tcf_ct_params_free
);
1300 static int tcf_ct_dump_key_val(struct sk_buff
*skb
,
1301 void *val
, int val_type
,
1302 void *mask
, int mask_type
,
1307 if (mask
&& !memchr_inv(mask
, 0, len
))
1310 err
= nla_put(skb
, val_type
, len
, val
);
1314 if (mask_type
!= TCA_CT_UNSPEC
) {
1315 err
= nla_put(skb
, mask_type
, len
, mask
);
1323 static int tcf_ct_dump_nat(struct sk_buff
*skb
, struct tcf_ct_params
*p
)
1325 struct nf_nat_range2
*range
= &p
->range
;
1327 if (!(p
->ct_action
& TCA_CT_ACT_NAT
))
1330 if (!(p
->ct_action
& (TCA_CT_ACT_NAT_SRC
| TCA_CT_ACT_NAT_DST
)))
1333 if (range
->flags
& NF_NAT_RANGE_MAP_IPS
) {
1334 if (p
->ipv4_range
) {
1335 if (nla_put_in_addr(skb
, TCA_CT_NAT_IPV4_MIN
,
1336 range
->min_addr
.ip
))
1338 if (nla_put_in_addr(skb
, TCA_CT_NAT_IPV4_MAX
,
1339 range
->max_addr
.ip
))
1342 if (nla_put_in6_addr(skb
, TCA_CT_NAT_IPV6_MIN
,
1343 &range
->min_addr
.in6
))
1345 if (nla_put_in6_addr(skb
, TCA_CT_NAT_IPV6_MAX
,
1346 &range
->max_addr
.in6
))
1351 if (range
->flags
& NF_NAT_RANGE_PROTO_SPECIFIED
) {
1352 if (nla_put_be16(skb
, TCA_CT_NAT_PORT_MIN
,
1353 range
->min_proto
.all
))
1355 if (nla_put_be16(skb
, TCA_CT_NAT_PORT_MAX
,
1356 range
->max_proto
.all
))
1363 static inline int tcf_ct_dump(struct sk_buff
*skb
, struct tc_action
*a
,
1366 unsigned char *b
= skb_tail_pointer(skb
);
1367 struct tcf_ct
*c
= to_ct(a
);
1368 struct tcf_ct_params
*p
;
1370 struct tc_ct opt
= {
1371 .index
= c
->tcf_index
,
1372 .refcnt
= refcount_read(&c
->tcf_refcnt
) - ref
,
1373 .bindcnt
= atomic_read(&c
->tcf_bindcnt
) - bind
,
1377 spin_lock_bh(&c
->tcf_lock
);
1378 p
= rcu_dereference_protected(c
->params
,
1379 lockdep_is_held(&c
->tcf_lock
));
1380 opt
.action
= c
->tcf_action
;
1382 if (tcf_ct_dump_key_val(skb
,
1383 &p
->ct_action
, TCA_CT_ACTION
,
1384 NULL
, TCA_CT_UNSPEC
,
1385 sizeof(p
->ct_action
)))
1386 goto nla_put_failure
;
1388 if (p
->ct_action
& TCA_CT_ACT_CLEAR
)
1391 if (IS_ENABLED(CONFIG_NF_CONNTRACK_MARK
) &&
1392 tcf_ct_dump_key_val(skb
,
1393 &p
->mark
, TCA_CT_MARK
,
1394 &p
->mark_mask
, TCA_CT_MARK_MASK
,
1396 goto nla_put_failure
;
1398 if (IS_ENABLED(CONFIG_NF_CONNTRACK_LABELS
) &&
1399 tcf_ct_dump_key_val(skb
,
1400 p
->labels
, TCA_CT_LABELS
,
1401 p
->labels_mask
, TCA_CT_LABELS_MASK
,
1403 goto nla_put_failure
;
1405 if (IS_ENABLED(CONFIG_NF_CONNTRACK_ZONES
) &&
1406 tcf_ct_dump_key_val(skb
,
1407 &p
->zone
, TCA_CT_ZONE
,
1408 NULL
, TCA_CT_UNSPEC
,
1410 goto nla_put_failure
;
1412 if (tcf_ct_dump_nat(skb
, p
))
1413 goto nla_put_failure
;
1416 if (nla_put(skb
, TCA_CT_PARMS
, sizeof(opt
), &opt
))
1417 goto nla_put_failure
;
1419 tcf_tm_dump(&t
, &c
->tcf_tm
);
1420 if (nla_put_64bit(skb
, TCA_CT_TM
, sizeof(t
), &t
, TCA_CT_PAD
))
1421 goto nla_put_failure
;
1422 spin_unlock_bh(&c
->tcf_lock
);
1426 spin_unlock_bh(&c
->tcf_lock
);
1431 static int tcf_ct_walker(struct net
*net
, struct sk_buff
*skb
,
1432 struct netlink_callback
*cb
, int type
,
1433 const struct tc_action_ops
*ops
,
1434 struct netlink_ext_ack
*extack
)
1436 struct tc_action_net
*tn
= net_generic(net
, ct_net_id
);
1438 return tcf_generic_walker(tn
, skb
, cb
, type
, ops
, extack
);
1441 static int tcf_ct_search(struct net
*net
, struct tc_action
**a
, u32 index
)
1443 struct tc_action_net
*tn
= net_generic(net
, ct_net_id
);
1445 return tcf_idr_search(tn
, a
, index
);
1448 static void tcf_stats_update(struct tc_action
*a
, u64 bytes
, u32 packets
,
1449 u64 lastuse
, bool hw
)
1451 struct tcf_ct
*c
= to_ct(a
);
1453 tcf_action_update_stats(a
, bytes
, packets
, false, hw
);
1454 c
->tcf_tm
.lastuse
= max_t(u64
, c
->tcf_tm
.lastuse
, lastuse
);
1457 static struct tc_action_ops act_ct_ops
= {
1460 .owner
= THIS_MODULE
,
1462 .dump
= tcf_ct_dump
,
1463 .init
= tcf_ct_init
,
1464 .cleanup
= tcf_ct_cleanup
,
1465 .walk
= tcf_ct_walker
,
1466 .lookup
= tcf_ct_search
,
1467 .stats_update
= tcf_stats_update
,
1468 .size
= sizeof(struct tcf_ct
),
1471 static __net_init
int ct_init_net(struct net
*net
)
1473 unsigned int n_bits
= sizeof_field(struct tcf_ct_params
, labels
) * 8;
1474 struct tc_ct_action_net
*tn
= net_generic(net
, ct_net_id
);
1476 if (nf_connlabels_get(net
, n_bits
- 1)) {
1478 pr_err("act_ct: Failed to set connlabels length");
1483 return tc_action_net_init(net
, &tn
->tn
, &act_ct_ops
);
1486 static void __net_exit
ct_exit_net(struct list_head
*net_list
)
1491 list_for_each_entry(net
, net_list
, exit_list
) {
1492 struct tc_ct_action_net
*tn
= net_generic(net
, ct_net_id
);
1495 nf_connlabels_put(net
);
1499 tc_action_net_exit(net_list
, ct_net_id
);
1502 static struct pernet_operations ct_net_ops
= {
1503 .init
= ct_init_net
,
1504 .exit_batch
= ct_exit_net
,
1506 .size
= sizeof(struct tc_ct_action_net
),
1509 static int __init
ct_init_module(void)
1513 act_ct_wq
= alloc_ordered_workqueue("act_ct_workqueue", 0);
1517 err
= tcf_ct_flow_tables_init();
1521 err
= tcf_register_action(&act_ct_ops
, &ct_net_ops
);
1528 destroy_workqueue(act_ct_wq
);
1530 tcf_ct_flow_tables_uninit();
1534 static void __exit
ct_cleanup_module(void)
1536 tcf_unregister_action(&act_ct_ops
, &ct_net_ops
);
1537 tcf_ct_flow_tables_uninit();
1538 destroy_workqueue(act_ct_wq
);
1541 void tcf_ct_flow_table_restore_skb(struct sk_buff
*skb
, unsigned long cookie
)
1543 enum ip_conntrack_info ctinfo
= cookie
& NFCT_INFOMASK
;
1546 ct
= (struct nf_conn
*)(cookie
& NFCT_PTRMASK
);
1547 nf_conntrack_get(&ct
->ct_general
);
1548 nf_ct_set(skb
, ct
, ctinfo
);
1550 EXPORT_SYMBOL_GPL(tcf_ct_flow_table_restore_skb
);
1552 module_init(ct_init_module
);
1553 module_exit(ct_cleanup_module
);
1554 MODULE_AUTHOR("Paul Blakey <paulb@mellanox.com>");
1555 MODULE_AUTHOR("Yossi Kuperman <yossiku@mellanox.com>");
1556 MODULE_AUTHOR("Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>");
1557 MODULE_DESCRIPTION("Connection tracking action");
1558 MODULE_LICENSE("GPL v2");