hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/openvswitch/conntrack.c
....@@ -1,14 +1,6 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015 Nicira, Inc.
3
- *
4
- * This program is free software; you can redistribute it and/or
5
- * modify it under the terms of version 2 of the GNU General Public
6
- * License as published by the Free Software Foundation.
7
- *
8
- * This program is distributed in the hope that it will be useful, but
9
- * WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11
- * General Public License for more details.
124 */
135
146 #include <linux/module.h>
....@@ -24,14 +16,13 @@
2416 #include <net/netfilter/nf_conntrack_helper.h>
2517 #include <net/netfilter/nf_conntrack_labels.h>
2618 #include <net/netfilter/nf_conntrack_seqadj.h>
19
+#include <net/netfilter/nf_conntrack_timeout.h>
2720 #include <net/netfilter/nf_conntrack_zones.h>
2821 #include <net/netfilter/ipv6/nf_defrag_ipv6.h>
2922 #include <net/ipv6_frag.h>
3023
31
-#ifdef CONFIG_NF_NAT_NEEDED
32
-#include <linux/netfilter/nf_nat.h>
33
-#include <net/netfilter/nf_nat_core.h>
34
-#include <net/netfilter/nf_nat_l3proto.h>
24
+#if IS_ENABLED(CONFIG_NF_NAT)
25
+#include <net/netfilter/nf_nat.h>
3526 #endif
3627
3728 #include "datapath.h"
....@@ -75,7 +66,9 @@
7566 u32 eventmask; /* Mask of 1 << IPCT_*. */
7667 struct md_mark mark;
7768 struct md_labels labels;
78
-#ifdef CONFIG_NF_NAT_NEEDED
69
+ char timeout[CTNL_TIMEOUT_NAME_MAX];
70
+ struct nf_ct_timeout *nf_ct_timeout;
71
+#if IS_ENABLED(CONFIG_NF_NAT)
7972 struct nf_nat_range2 range; /* Only present for SRC NAT and DST NAT. */
8073 #endif
8174 };
....@@ -157,7 +150,7 @@
157150 static u32 ovs_ct_get_mark(const struct nf_conn *ct)
158151 {
159152 #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
160
- return ct ? ct->mark : 0;
153
+ return ct ? READ_ONCE(ct->mark) : 0;
161154 #else
162155 return 0;
163156 #endif
....@@ -343,9 +336,9 @@
343336 #if IS_ENABLED(CONFIG_NF_CONNTRACK_MARK)
344337 u32 new_mark;
345338
346
- new_mark = ct_mark | (ct->mark & ~(mask));
347
- if (ct->mark != new_mark) {
348
- ct->mark = new_mark;
339
+ new_mark = ct_mark | (READ_ONCE(ct->mark) & ~(mask));
340
+ if (READ_ONCE(ct->mark) != new_mark) {
341
+ WRITE_ONCE(ct->mark, new_mark);
349342 if (nf_ct_is_confirmed(ct))
350343 nf_conntrack_event_cache(IPCT_MARK, ct);
351344 key->ct.mark = new_mark;
....@@ -534,6 +527,11 @@
534527 return -EPFNOSUPPORT;
535528 }
536529
530
+ /* The key extracted from the fragment that completed this datagram
531
+ * likely didn't have an L4 header, so regenerate it.
532
+ */
533
+ ovs_flow_key_update_l3l4(skb, key);
534
+
537535 key->ip.frag = OVS_FRAG_TYPE_NONE;
538536 skb_clear_hash(skb);
539537 skb->ignore_df = 1;
....@@ -624,7 +622,7 @@
624622 if (natted) {
625623 struct nf_conntrack_tuple inverse;
626624
627
- if (!nf_ct_invert_tuplepr(&inverse, &tuple)) {
625
+ if (!nf_ct_invert_tuple(&inverse, &tuple)) {
628626 pr_debug("ovs_ct_find_existing: Inversion failed!\n");
629627 return NULL;
630628 }
....@@ -707,6 +705,14 @@
707705 if (help && rcu_access_pointer(help->helper) != info->helper)
708706 return false;
709707 }
708
+ if (info->nf_ct_timeout) {
709
+ struct nf_conn_timeout *timeout_ext;
710
+
711
+ timeout_ext = nf_ct_timeout_find(ct);
712
+ if (!timeout_ext || info->nf_ct_timeout !=
713
+ rcu_dereference(timeout_ext->timeout))
714
+ return false;
715
+ }
710716 /* Force conntrack entry direction to the current packet? */
711717 if (info->force && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) {
712718 /* Delete the conntrack entry if confirmed, else just release
....@@ -723,90 +729,7 @@
723729 return ct_executed;
724730 }
725731
726
-#ifdef CONFIG_NF_NAT_NEEDED
727
-/* Modelled after nf_nat_ipv[46]_fn().
728
- * range is only used for new, uninitialized NAT state.
729
- * Returns either NF_ACCEPT or NF_DROP.
730
- */
731
-static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
732
- enum ip_conntrack_info ctinfo,
733
- const struct nf_nat_range2 *range,
734
- enum nf_nat_manip_type maniptype)
735
-{
736
- int hooknum, nh_off, err = NF_ACCEPT;
737
-
738
- nh_off = skb_network_offset(skb);
739
- skb_pull_rcsum(skb, nh_off);
740
-
741
- /* See HOOK2MANIP(). */
742
- if (maniptype == NF_NAT_MANIP_SRC)
743
- hooknum = NF_INET_LOCAL_IN; /* Source NAT */
744
- else
745
- hooknum = NF_INET_LOCAL_OUT; /* Destination NAT */
746
-
747
- switch (ctinfo) {
748
- case IP_CT_RELATED:
749
- case IP_CT_RELATED_REPLY:
750
- if (IS_ENABLED(CONFIG_NF_NAT_IPV4) &&
751
- skb->protocol == htons(ETH_P_IP) &&
752
- ip_hdr(skb)->protocol == IPPROTO_ICMP) {
753
- if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo,
754
- hooknum))
755
- err = NF_DROP;
756
- goto push;
757
- } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) &&
758
- skb->protocol == htons(ETH_P_IPV6)) {
759
- __be16 frag_off;
760
- u8 nexthdr = ipv6_hdr(skb)->nexthdr;
761
- int hdrlen = ipv6_skip_exthdr(skb,
762
- sizeof(struct ipv6hdr),
763
- &nexthdr, &frag_off);
764
-
765
- if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
766
- if (!nf_nat_icmpv6_reply_translation(skb, ct,
767
- ctinfo,
768
- hooknum,
769
- hdrlen))
770
- err = NF_DROP;
771
- goto push;
772
- }
773
- }
774
- /* Non-ICMP, fall thru to initialize if needed. */
775
- /* fall through */
776
- case IP_CT_NEW:
777
- /* Seen it before? This can happen for loopback, retrans,
778
- * or local packets.
779
- */
780
- if (!nf_nat_initialized(ct, maniptype)) {
781
- /* Initialize according to the NAT action. */
782
- err = (range && range->flags & NF_NAT_RANGE_MAP_IPS)
783
- /* Action is set up to establish a new
784
- * mapping.
785
- */
786
- ? nf_nat_setup_info(ct, range, maniptype)
787
- : nf_nat_alloc_null_binding(ct, hooknum);
788
- if (err != NF_ACCEPT)
789
- goto push;
790
- }
791
- break;
792
-
793
- case IP_CT_ESTABLISHED:
794
- case IP_CT_ESTABLISHED_REPLY:
795
- break;
796
-
797
- default:
798
- err = NF_DROP;
799
- goto push;
800
- }
801
-
802
- err = nf_nat_packet(ct, ctinfo, hooknum, skb);
803
-push:
804
- skb_push(skb, nh_off);
805
- skb_postpush_rcsum(skb, skb->data, nh_off);
806
-
807
- return err;
808
-}
809
-
732
+#if IS_ENABLED(CONFIG_NF_NAT)
810733 static void ovs_nat_update_key(struct sw_flow_key *key,
811734 const struct sk_buff *skb,
812735 enum nf_nat_manip_type maniptype)
....@@ -858,6 +781,93 @@
858781 }
859782 }
860783
784
+/* Modelled after nf_nat_ipv[46]_fn().
785
+ * range is only used for new, uninitialized NAT state.
786
+ * Returns either NF_ACCEPT or NF_DROP.
787
+ */
788
+static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct,
789
+ enum ip_conntrack_info ctinfo,
790
+ const struct nf_nat_range2 *range,
791
+ enum nf_nat_manip_type maniptype, struct sw_flow_key *key)
792
+{
793
+ int hooknum, nh_off, err = NF_ACCEPT;
794
+
795
+ nh_off = skb_network_offset(skb);
796
+ skb_pull_rcsum(skb, nh_off);
797
+
798
+ /* See HOOK2MANIP(). */
799
+ if (maniptype == NF_NAT_MANIP_SRC)
800
+ hooknum = NF_INET_LOCAL_IN; /* Source NAT */
801
+ else
802
+ hooknum = NF_INET_LOCAL_OUT; /* Destination NAT */
803
+
804
+ switch (ctinfo) {
805
+ case IP_CT_RELATED:
806
+ case IP_CT_RELATED_REPLY:
807
+ if (IS_ENABLED(CONFIG_NF_NAT) &&
808
+ skb->protocol == htons(ETH_P_IP) &&
809
+ ip_hdr(skb)->protocol == IPPROTO_ICMP) {
810
+ if (!nf_nat_icmp_reply_translation(skb, ct, ctinfo,
811
+ hooknum))
812
+ err = NF_DROP;
813
+ goto push;
814
+ } else if (IS_ENABLED(CONFIG_IPV6) &&
815
+ skb->protocol == htons(ETH_P_IPV6)) {
816
+ __be16 frag_off;
817
+ u8 nexthdr = ipv6_hdr(skb)->nexthdr;
818
+ int hdrlen = ipv6_skip_exthdr(skb,
819
+ sizeof(struct ipv6hdr),
820
+ &nexthdr, &frag_off);
821
+
822
+ if (hdrlen >= 0 && nexthdr == IPPROTO_ICMPV6) {
823
+ if (!nf_nat_icmpv6_reply_translation(skb, ct,
824
+ ctinfo,
825
+ hooknum,
826
+ hdrlen))
827
+ err = NF_DROP;
828
+ goto push;
829
+ }
830
+ }
831
+ /* Non-ICMP, fall thru to initialize if needed. */
832
+ fallthrough;
833
+ case IP_CT_NEW:
834
+ /* Seen it before? This can happen for loopback, retrans,
835
+ * or local packets.
836
+ */
837
+ if (!nf_nat_initialized(ct, maniptype)) {
838
+ /* Initialize according to the NAT action. */
839
+ err = (range && range->flags & NF_NAT_RANGE_MAP_IPS)
840
+ /* Action is set up to establish a new
841
+ * mapping.
842
+ */
843
+ ? nf_nat_setup_info(ct, range, maniptype)
844
+ : nf_nat_alloc_null_binding(ct, hooknum);
845
+ if (err != NF_ACCEPT)
846
+ goto push;
847
+ }
848
+ break;
849
+
850
+ case IP_CT_ESTABLISHED:
851
+ case IP_CT_ESTABLISHED_REPLY:
852
+ break;
853
+
854
+ default:
855
+ err = NF_DROP;
856
+ goto push;
857
+ }
858
+
859
+ err = nf_nat_packet(ct, ctinfo, hooknum, skb);
860
+push:
861
+ skb_push(skb, nh_off);
862
+ skb_postpush_rcsum(skb, skb->data, nh_off);
863
+
864
+ /* Update the flow key if NAT successful. */
865
+ if (err == NF_ACCEPT)
866
+ ovs_nat_update_key(key, skb, maniptype);
867
+
868
+ return err;
869
+}
870
+
861871 /* Returns NF_DROP if the packet should be dropped, NF_ACCEPT otherwise. */
862872 static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
863873 const struct ovs_conntrack_info *info,
....@@ -897,7 +907,7 @@
897907 } else {
898908 return NF_ACCEPT; /* Connection is not NATed. */
899909 }
900
- err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype);
910
+ err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range, maniptype, key);
901911
902912 if (err == NF_ACCEPT && ct->status & IPS_DST_NAT) {
903913 if (ct->status & IPS_SRC_NAT) {
....@@ -907,20 +917,16 @@
907917 maniptype = NF_NAT_MANIP_SRC;
908918
909919 err = ovs_ct_nat_execute(skb, ct, ctinfo, &info->range,
910
- maniptype);
920
+ maniptype, key);
911921 } else if (CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) {
912922 err = ovs_ct_nat_execute(skb, ct, ctinfo, NULL,
913
- NF_NAT_MANIP_SRC);
923
+ NF_NAT_MANIP_SRC, key);
914924 }
915925 }
916926
917
- /* Mark NAT done if successful and update the flow key. */
918
- if (err == NF_ACCEPT)
919
- ovs_nat_update_key(key, skb, maniptype);
920
-
921927 return err;
922928 }
923
-#else /* !CONFIG_NF_NAT_NEEDED */
929
+#else /* !CONFIG_NF_NAT */
924930 static int ovs_ct_nat(struct net *net, struct sw_flow_key *key,
925931 const struct ovs_conntrack_info *info,
926932 struct sk_buff *skb, struct nf_conn *ct,
....@@ -950,6 +956,11 @@
950956 struct nf_conn *ct;
951957
952958 if (!cached) {
959
+ struct nf_hook_state state = {
960
+ .hook = NF_INET_PRE_ROUTING,
961
+ .pf = info->family,
962
+ .net = net,
963
+ };
953964 struct nf_conn *tmpl = info->ct;
954965 int err;
955966
....@@ -961,8 +972,7 @@
961972 nf_ct_set(skb, tmpl, IP_CT_NEW);
962973 }
963974
964
- err = nf_conntrack_in(net, info->family,
965
- NF_INET_PRE_ROUTING, skb);
975
+ err = nf_conntrack_in(skb, &state);
966976 if (err != NF_ACCEPT)
967977 return -ENOENT;
968978
....@@ -978,6 +988,8 @@
978988
979989 ct = nf_ct_get(skb, &ctinfo);
980990 if (ct) {
991
+ bool add_helper = false;
992
+
981993 /* Packets starting a new connection must be NATted before the
982994 * helper, so that the helper knows about the NAT. We enforce
983995 * this by delaying both NAT and helper calls for unconfirmed
....@@ -995,24 +1007,33 @@
9951007 }
9961008
9971009 /* Userspace may decide to perform a ct lookup without a helper
998
- * specified followed by a (recirculate and) commit with one.
999
- * Therefore, for unconfirmed connections which we will commit,
1000
- * we need to attach the helper here.
1010
+ * specified followed by a (recirculate and) commit with one,
1011
+ * or attach a helper in a later commit. Therefore, for
1012
+ * connections which we will commit, we may need to attach
1013
+ * the helper here.
10011014 */
1002
- if (!nf_ct_is_confirmed(ct) && info->commit &&
1003
- info->helper && !nfct_help(ct)) {
1015
+ if (info->commit && info->helper && !nfct_help(ct)) {
10041016 int err = __nf_ct_try_assign_helper(ct, info->ct,
10051017 GFP_ATOMIC);
10061018 if (err)
10071019 return err;
1020
+ add_helper = true;
1021
+
1022
+ /* helper installed, add seqadj if NAT is required */
1023
+ if (info->nat && !nfct_seqadj(ct)) {
1024
+ if (!nfct_seqadj_ext_add(ct))
1025
+ return -EINVAL;
1026
+ }
10081027 }
10091028
10101029 /* Call the helper only if:
1011
- * - nf_conntrack_in() was executed above ("!cached") for a
1012
- * confirmed connection, or
1030
+ * - nf_conntrack_in() was executed above ("!cached") or a
1031
+ * helper was just attached ("add_helper") for a confirmed
1032
+ * connection, or
10131033 * - When committing an unconfirmed connection.
10141034 */
1015
- if ((nf_ct_is_confirmed(ct) ? !cached : info->commit) &&
1035
+ if ((nf_ct_is_confirmed(ct) ? !cached || add_helper :
1036
+ info->commit) &&
10161037 ovs_ct_helper(skb, info->family) != NF_ACCEPT) {
10171038 return -EINVAL;
10181039 }
....@@ -1179,7 +1200,7 @@
11791200 &ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple);
11801201 if (err) {
11811202 net_warn_ratelimited("openvswitch: zone: %u "
1182
- "execeeds conntrack limit\n",
1203
+ "exceeds conntrack limit\n",
11831204 info->zone.id);
11841205 return err;
11851206 }
....@@ -1303,7 +1324,8 @@
13031324 if (skb_nfct(skb)) {
13041325 nf_conntrack_put(skb_nfct(skb));
13051326 nf_ct_set(skb, NULL, IP_CT_UNTRACKED);
1306
- ovs_ct_fill_key(skb, key);
1327
+ if (key)
1328
+ ovs_ct_fill_key(skb, key);
13071329 }
13081330
13091331 return 0;
....@@ -1314,6 +1336,7 @@
13141336 {
13151337 struct nf_conntrack_helper *helper;
13161338 struct nf_conn_help *help;
1339
+ int ret = 0;
13171340
13181341 helper = nf_conntrack_helper_try_module_get(name, info->family,
13191342 key->ip.proto);
....@@ -1328,16 +1351,24 @@
13281351 return -ENOMEM;
13291352 }
13301353
1354
+#if IS_ENABLED(CONFIG_NF_NAT)
1355
+ if (info->nat) {
1356
+ ret = nf_nat_helper_try_module_get(name, info->family,
1357
+ key->ip.proto);
1358
+ if (ret) {
1359
+ nf_conntrack_helper_put(helper);
1360
+ OVS_NLERR(log, "Failed to load \"%s\" NAT helper, error: %d",
1361
+ name, ret);
1362
+ return ret;
1363
+ }
1364
+ }
1365
+#endif
13311366 rcu_assign_pointer(help->helper, helper);
13321367 info->helper = helper;
1333
-
1334
- if (info->nat)
1335
- request_module("ip_nat_%s", name);
1336
-
1337
- return 0;
1368
+ return ret;
13381369 }
13391370
1340
-#ifdef CONFIG_NF_NAT_NEEDED
1371
+#if IS_ENABLED(CONFIG_NF_NAT)
13411372 static int parse_nat(const struct nlattr *attr,
13421373 struct ovs_conntrack_info *info, bool log)
13431374 {
....@@ -1474,12 +1505,14 @@
14741505 .maxlen = sizeof(struct md_labels) },
14751506 [OVS_CT_ATTR_HELPER] = { .minlen = 1,
14761507 .maxlen = NF_CT_HELPER_NAME_LEN },
1477
-#ifdef CONFIG_NF_NAT_NEEDED
1508
+#if IS_ENABLED(CONFIG_NF_NAT)
14781509 /* NAT length is checked when parsing the nested attributes. */
14791510 [OVS_CT_ATTR_NAT] = { .minlen = 0, .maxlen = INT_MAX },
14801511 #endif
14811512 [OVS_CT_ATTR_EVENTMASK] = { .minlen = sizeof(u32),
14821513 .maxlen = sizeof(u32) },
1514
+ [OVS_CT_ATTR_TIMEOUT] = { .minlen = 1,
1515
+ .maxlen = CTNL_TIMEOUT_NAME_MAX },
14831516 };
14841517
14851518 static int parse_ct(const struct nlattr *attr, struct ovs_conntrack_info *info,
....@@ -1512,7 +1545,7 @@
15121545 switch (type) {
15131546 case OVS_CT_ATTR_FORCE_COMMIT:
15141547 info->force = true;
1515
- /* fall through. */
1548
+ fallthrough;
15161549 case OVS_CT_ATTR_COMMIT:
15171550 info->commit = true;
15181551 break;
....@@ -1552,7 +1585,7 @@
15521585 return -EINVAL;
15531586 }
15541587 break;
1555
-#ifdef CONFIG_NF_NAT_NEEDED
1588
+#if IS_ENABLED(CONFIG_NF_NAT)
15561589 case OVS_CT_ATTR_NAT: {
15571590 int err = parse_nat(a, info, log);
15581591
....@@ -1565,6 +1598,15 @@
15651598 info->have_eventmask = true;
15661599 info->eventmask = nla_get_u32(a);
15671600 break;
1601
+#ifdef CONFIG_NF_CONNTRACK_TIMEOUT
1602
+ case OVS_CT_ATTR_TIMEOUT:
1603
+ memcpy(info->timeout, nla_data(a), nla_len(a));
1604
+ if (!memchr(info->timeout, '\0', nla_len(a))) {
1605
+ OVS_NLERR(log, "Invalid conntrack timeout");
1606
+ return -EINVAL;
1607
+ }
1608
+ break;
1609
+#endif
15681610
15691611 default:
15701612 OVS_NLERR(log, "Unknown conntrack attr (%d)",
....@@ -1646,6 +1688,18 @@
16461688 OVS_NLERR(log, "Failed to allocate conntrack template");
16471689 return -ENOMEM;
16481690 }
1691
+
1692
+ if (ct_info.timeout[0]) {
1693
+ if (nf_ct_set_timeout(net, ct_info.ct, family, key->ip.proto,
1694
+ ct_info.timeout))
1695
+ pr_info_ratelimited("Failed to associated timeout "
1696
+ "policy `%s'\n", ct_info.timeout);
1697
+ else
1698
+ ct_info.nf_ct_timeout = rcu_dereference(
1699
+ nf_ct_timeout_find(ct_info.ct)->timeout);
1700
+
1701
+ }
1702
+
16491703 if (helper) {
16501704 err = ovs_ct_add_helper(&ct_info, helper, key, log);
16511705 if (err)
....@@ -1665,13 +1719,13 @@
16651719 return err;
16661720 }
16671721
1668
-#ifdef CONFIG_NF_NAT_NEEDED
1722
+#if IS_ENABLED(CONFIG_NF_NAT)
16691723 static bool ovs_ct_nat_to_attr(const struct ovs_conntrack_info *info,
16701724 struct sk_buff *skb)
16711725 {
16721726 struct nlattr *start;
16731727
1674
- start = nla_nest_start(skb, OVS_CT_ATTR_NAT);
1728
+ start = nla_nest_start_noflag(skb, OVS_CT_ATTR_NAT);
16751729 if (!start)
16761730 return false;
16771731
....@@ -1686,7 +1740,7 @@
16861740 }
16871741
16881742 if (info->range.flags & NF_NAT_RANGE_MAP_IPS) {
1689
- if (IS_ENABLED(CONFIG_NF_NAT_IPV4) &&
1743
+ if (IS_ENABLED(CONFIG_NF_NAT) &&
16901744 info->family == NFPROTO_IPV4) {
16911745 if (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MIN,
16921746 info->range.min_addr.ip) ||
....@@ -1695,7 +1749,7 @@
16951749 (nla_put_in_addr(skb, OVS_NAT_ATTR_IP_MAX,
16961750 info->range.max_addr.ip))))
16971751 return false;
1698
- } else if (IS_ENABLED(CONFIG_NF_NAT_IPV6) &&
1752
+ } else if (IS_ENABLED(CONFIG_IPV6) &&
16991753 info->family == NFPROTO_IPV6) {
17001754 if (nla_put_in6_addr(skb, OVS_NAT_ATTR_IP_MIN,
17011755 &info->range.min_addr.in6) ||
....@@ -1738,7 +1792,7 @@
17381792 {
17391793 struct nlattr *start;
17401794
1741
- start = nla_nest_start(skb, OVS_ACTION_ATTR_CT);
1795
+ start = nla_nest_start_noflag(skb, OVS_ACTION_ATTR_CT);
17421796 if (!start)
17431797 return -EMSGSIZE;
17441798
....@@ -1766,8 +1820,12 @@
17661820 if (ct_info->have_eventmask &&
17671821 nla_put_u32(skb, OVS_CT_ATTR_EVENTMASK, ct_info->eventmask))
17681822 return -EMSGSIZE;
1823
+ if (ct_info->timeout[0]) {
1824
+ if (nla_put_string(skb, OVS_CT_ATTR_TIMEOUT, ct_info->timeout))
1825
+ return -EMSGSIZE;
1826
+ }
17691827
1770
-#ifdef CONFIG_NF_NAT_NEEDED
1828
+#if IS_ENABLED(CONFIG_NF_NAT)
17711829 if (ct_info->nat && !ovs_ct_nat_to_attr(ct_info, skb))
17721830 return -EMSGSIZE;
17731831 #endif
....@@ -1785,10 +1843,18 @@
17851843
17861844 static void __ovs_ct_free_action(struct ovs_conntrack_info *ct_info)
17871845 {
1788
- if (ct_info->helper)
1846
+ if (ct_info->helper) {
1847
+#if IS_ENABLED(CONFIG_NF_NAT)
1848
+ if (ct_info->nat)
1849
+ nf_nat_helper_put(ct_info->helper);
1850
+#endif
17891851 nf_conntrack_helper_put(ct_info->helper);
1790
- if (ct_info->ct)
1852
+ }
1853
+ if (ct_info->ct) {
1854
+ if (ct_info->timeout[0])
1855
+ nf_ct_destroy_timeout(ct_info->ct);
17911856 nf_ct_tmpl_free(ct_info->ct);
1857
+ }
17921858 }
17931859
17941860 #if IS_ENABLED(CONFIG_NETFILTER_CONNCOUNT)
....@@ -1836,11 +1902,12 @@
18361902 struct hlist_head *head = &info->limits[i];
18371903 struct ovs_ct_limit *ct_limit;
18381904
1839
- hlist_for_each_entry_rcu(ct_limit, head, hlist_node)
1905
+ hlist_for_each_entry_rcu(ct_limit, head, hlist_node,
1906
+ lockdep_ovsl_is_held())
18401907 kfree_rcu(ct_limit, rcu);
18411908 }
1842
- kfree(ovs_net->ct_limit_info->limits);
1843
- kfree(ovs_net->ct_limit_info);
1909
+ kfree(info->limits);
1910
+ kfree(info);
18441911 }
18451912
18461913 static struct sk_buff *
....@@ -1958,16 +2025,12 @@
19582025 static int ovs_ct_limit_get_default_limit(struct ovs_ct_limit_info *info,
19592026 struct sk_buff *reply)
19602027 {
1961
- struct ovs_zone_limit zone_limit;
1962
- int err;
2028
+ struct ovs_zone_limit zone_limit = {
2029
+ .zone_id = OVS_ZONE_LIMIT_DEFAULT_ZONE,
2030
+ .limit = info->default_limit,
2031
+ };
19632032
1964
- zone_limit.zone_id = OVS_ZONE_LIMIT_DEFAULT_ZONE;
1965
- zone_limit.limit = info->default_limit;
1966
- err = nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit);
1967
- if (err)
1968
- return err;
1969
-
1970
- return 0;
2033
+ return nla_put_nohdr(reply, sizeof(zone_limit), &zone_limit);
19712034 }
19722035
19732036 static int __ovs_ct_limit_get_zone_limit(struct net *net,
....@@ -2141,7 +2204,11 @@
21412204 if (IS_ERR(reply))
21422205 return PTR_ERR(reply);
21432206
2144
- nla_reply = nla_nest_start(reply, OVS_CT_LIMIT_ATTR_ZONE_LIMIT);
2207
+ nla_reply = nla_nest_start_noflag(reply, OVS_CT_LIMIT_ATTR_ZONE_LIMIT);
2208
+ if (!nla_reply) {
2209
+ err = -EMSGSIZE;
2210
+ goto exit_err;
2211
+ }
21452212
21462213 if (a[OVS_CT_LIMIT_ATTR_ZONE_LIMIT]) {
21472214 err = ovs_ct_limit_get_zone_limit(
....@@ -2165,22 +2232,22 @@
21652232 return err;
21662233 }
21672234
2168
-static struct genl_ops ct_limit_genl_ops[] = {
2235
+static const struct genl_small_ops ct_limit_genl_ops[] = {
21692236 { .cmd = OVS_CT_LIMIT_CMD_SET,
2237
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
21702238 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN
21712239 * privilege. */
2172
- .policy = ct_limit_policy,
21732240 .doit = ovs_ct_limit_cmd_set,
21742241 },
21752242 { .cmd = OVS_CT_LIMIT_CMD_DEL,
2243
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
21762244 .flags = GENL_ADMIN_PERM, /* Requires CAP_NET_ADMIN
21772245 * privilege. */
2178
- .policy = ct_limit_policy,
21792246 .doit = ovs_ct_limit_cmd_del,
21802247 },
21812248 { .cmd = OVS_CT_LIMIT_CMD_GET,
2249
+ .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
21822250 .flags = 0, /* OK for unprivileged users. */
2183
- .policy = ct_limit_policy,
21842251 .doit = ovs_ct_limit_cmd_get,
21852252 },
21862253 };
....@@ -2194,10 +2261,11 @@
21942261 .name = OVS_CT_LIMIT_FAMILY,
21952262 .version = OVS_CT_LIMIT_VERSION,
21962263 .maxattr = OVS_CT_LIMIT_ATTR_MAX,
2264
+ .policy = ct_limit_policy,
21972265 .netnsok = true,
21982266 .parallel_ops = true,
2199
- .ops = ct_limit_genl_ops,
2200
- .n_ops = ARRAY_SIZE(ct_limit_genl_ops),
2267
+ .small_ops = ct_limit_genl_ops,
2268
+ .n_small_ops = ARRAY_SIZE(ct_limit_genl_ops),
22012269 .mcgrps = &ovs_ct_limit_multicast_group,
22022270 .n_mcgrps = 1,
22032271 .module = THIS_MODULE,