Pablo Neira Ayuso says: ==================== Netfilter fixes for net The following patchset contains Netfilter fixes for net: 1) Fix a deadlock when module is requested via netlink_bind() in nfnetlink, from Florian Westphal. 2) Fix ipt_rpfilter and ip6t_rpfilter with VRF, from Miaohe Lin. 3) Skip master comparison in SIP helper to fix expectation clash under two valid scenarios, from xiao ruizhu. 4) Remove obsolete comments in nf_conntrack codebase, from Yonatan Goldschmidt. 5) Fix redirect extension module autoload, from Christian Hesse. 6) Fix incorrect mssg option sent to client in synproxy, from Fernando Fernandez. 7) Fix incorrect window calculations in TCP conntrack, from Florian Westphal. 8) Don't bail out when updating basechain policy due to recent offload works, also from Florian. 9) Allow symhash to use modulus 1 as other hash extensions do, from Laura.Garcia. 10) Missing NAT chain module autoload for the inet family, from Phil Sutter. 11) Fix missing adjustment of TCP RST packet in synproxy, from Fernando Fernandez. 12) Skip EAGAIN path when nft_meta_bridge is built-in or not selected. 13) Conntrack bridge does not depend on nf_tables_bridge. 14) Turn NF_TABLES_BRIDGE into tristate to fix possible link break of nft_meta_bridge, from Arnd Bergmann. ====================
Unified · Split
| @@ -1,7 +1,6 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0-only */ | 1 | /* SPDX-License-Identifier: GPL-2.0-only */ |
| 2 | /**************************************************************************** | 2 | /**************************************************************************** |
| 3 | * ip_conntrack_h323_asn1.h - BER and PER decoding library for H.323 | 3 | * BER and PER decoding library for H.323 conntrack/NAT module. |
| 4 | * conntrack/NAT module. | ||
| 5 | * | 4 | * |
| 6 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> | 5 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> |
| 7 | * | 6 | * |
| @@ -76,6 +76,11 @@ struct nf_conntrack_expect_policy { · 75 unmodified lines | |||
| 76 | #define NF_CT_EXPECT_CLASS_DEFAULT 0 | 76 | #define NF_CT_EXPECT_CLASS_DEFAULT 0 |
| 77 | #define NF_CT_EXPECT_MAX_CNT 255 | 77 | #define NF_CT_EXPECT_MAX_CNT 255 |
| 78 | 78 | ||
| 79 | /* Allow to reuse expectations with the same tuples from different master | ||
| 80 | * conntracks. | ||
| 81 | */ | ||
| 82 | #define NF_CT_EXP_F_SKIP_MASTER 0x1 | ||
| 83 | |||
| 79 | int nf_conntrack_expect_pernet_init(struct net *net); | 84 | int nf_conntrack_expect_pernet_init(struct net *net); |
| 80 | void nf_conntrack_expect_pernet_fini(struct net *net); | 85 | void nf_conntrack_expect_pernet_fini(struct net *net); |
| 81 | 86 | ||
| @@ -122,10 +127,11 @@ void nf_ct_expect_init(struct nf_conntrack_expect *, unsigned int, u_int8_t, · 40 unmodified lines | |||
| 122 | u_int8_t, const __be16 *, const __be16 *); | 127 | u_int8_t, const __be16 *, const __be16 *); |
| 123 | void nf_ct_expect_put(struct nf_conntrack_expect *exp); | 128 | void nf_ct_expect_put(struct nf_conntrack_expect *exp); |
| 124 | int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, | 129 | int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, |
| 125 | u32 portid, int report); | 130 | u32 portid, int report, unsigned int flags); |
| 126 | static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect) | 131 | static inline int nf_ct_expect_related(struct nf_conntrack_expect *expect, |
| 132 | unsigned int flags) | ||
| 127 | { | 133 | { |
| 128 | return nf_ct_expect_related_report(expect, 0, 0); | 134 | return nf_ct_expect_related_report(expect, 0, 0, flags); |
| 129 | } | 135 | } |
| 130 | 136 | ||
| 131 | #endif /*_NF_CONNTRACK_EXPECT_H*/ | 137 | #endif /*_NF_CONNTRACK_EXPECT_H*/ |
| @@ -68,6 +68,7 @@ struct synproxy_options { · 67 unmodified lines | |||
| 68 | u8 options; | 68 | u8 options; |
| 69 | u8 wscale; | 69 | u8 wscale; |
| 70 | u16 mss; | 70 | u16 mss; |
| 71 | u16 mss_encode; | ||
| 71 | u32 tsval; | 72 | u32 tsval; |
| 72 | u32 tsecr; | 73 | u32 tsecr; |
| 73 | }; | 74 | }; |
| @@ -6,7 +6,7 @@ · 5 unmodified lines | |||
| 6 | menuconfig NF_TABLES_BRIDGE | 6 | menuconfig NF_TABLES_BRIDGE |
| 7 | depends on BRIDGE && NETFILTER && NF_TABLES | 7 | depends on BRIDGE && NETFILTER && NF_TABLES |
| 8 | select NETFILTER_FAMILY_BRIDGE | 8 | select NETFILTER_FAMILY_BRIDGE |
| 9 | bool "Ethernet Bridge nf_tables support" | 9 | tristate "Ethernet Bridge nf_tables support" |
| 10 | 10 | ||
| 11 | if NF_TABLES_BRIDGE | 11 | if NF_TABLES_BRIDGE |
| 12 | 12 | ||
| @@ -25,6 +25,8 @@ config NF_LOG_BRIDGE · 12 unmodified lines | |||
| 25 | tristate "Bridge packet logging" | 25 | tristate "Bridge packet logging" |
| 26 | select NF_LOG_COMMON | 26 | select NF_LOG_COMMON |
| 27 | 27 | ||
| 28 | endif # NF_TABLES_BRIDGE | ||
| 29 | |||
| 28 | config NF_CONNTRACK_BRIDGE | 30 | config NF_CONNTRACK_BRIDGE |
| 29 | tristate "IPv4/IPV6 bridge connection tracking support" | 31 | tristate "IPv4/IPV6 bridge connection tracking support" |
| 30 | depends on NF_CONNTRACK | 32 | depends on NF_CONNTRACK |
| @@ -39,8 +41,6 @@ config NF_CONNTRACK_BRIDGE · 8 unmodified lines | |||
| 39 | 41 | ||
| 40 | To compile it as a module, choose M here. If unsure, say N. | 42 | To compile it as a module, choose M here. If unsure, say N. |
| 41 | 43 | ||
| 42 | endif # NF_TABLES_BRIDGE | ||
| 43 | |||
| 44 | menuconfig BRIDGE_NF_EBTABLES | 44 | menuconfig BRIDGE_NF_EBTABLES |
| 45 | tristate "Ethernet Bridge tables (ebtables) support" | 45 | tristate "Ethernet Bridge tables (ebtables) support" |
| 46 | depends on BRIDGE && NETFILTER && NETFILTER_XTABLES | 46 | depends on BRIDGE && NETFILTER && NETFILTER_XTABLES |
| @@ -416,8 +416,8 @@ clusterip_tg(struct sk_buff *skb, const struct xt_action_param *par) · 415 unmodified lines | |||
| 416 | ctinfo == IP_CT_RELATED_REPLY)) | 416 | ctinfo == IP_CT_RELATED_REPLY)) |
| 417 | return XT_CONTINUE; | 417 | return XT_CONTINUE; |
| 418 | 418 | ||
| 419 | /* ip_conntrack_icmp guarantees us that we only have ICMP_ECHO, | 419 | /* nf_conntrack_proto_icmp guarantees us that we only have ICMP_ECHO, |
| 420 | * TIMESTAMP, INFO_REQUEST or ADDRESS type icmp packets from here | 420 | * TIMESTAMP, INFO_REQUEST or ICMP_ADDRESS type icmp packets from here |
| 421 | * on, which all have an ID field [relevant for hashing]. */ | 421 | * on, which all have an ID field [relevant for hashing]. */ |
| 422 | 422 | ||
| 423 | hash = clusterip_hashfn(skb, cipinfo->config); | 423 | hash = clusterip_hashfn(skb, cipinfo->config); |
| @@ -36,6 +36,8 @@ synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) · 35 unmodified lines | |||
| 36 | opts.options |= XT_SYNPROXY_OPT_ECN; | 36 | opts.options |= XT_SYNPROXY_OPT_ECN; |
| 37 | 37 | ||
| 38 | opts.options &= info->options; | 38 | opts.options &= info->options; |
| 39 | opts.mss_encode = opts.mss; | ||
| 40 | opts.mss = info->mss; | ||
| 39 | if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) | 41 | if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) |
| 40 | synproxy_init_timestamp_cookie(info, &opts); | 42 | synproxy_init_timestamp_cookie(info, &opts); |
| 41 | else | 43 | else |
| @@ -78,6 +78,7 @@ static bool rpfilter_mt(const struct sk_buff *skb, struct xt_action_param *par) · 77 unmodified lines | |||
| 78 | flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0; | 78 | flow.flowi4_mark = info->flags & XT_RPFILTER_VALID_MARK ? skb->mark : 0; |
| 79 | flow.flowi4_tos = RT_TOS(iph->tos); | 79 | flow.flowi4_tos = RT_TOS(iph->tos); |
| 80 | flow.flowi4_scope = RT_SCOPE_UNIVERSE; | 80 | flow.flowi4_scope = RT_SCOPE_UNIVERSE; |
| 81 | flow.flowi4_oif = l3mdev_master_ifindex_rcu(xt_in(par)); | ||
| 81 | 82 | ||
| 82 | return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert; | 83 | return rpfilter_lookup_reverse(xt_net(par), &flow, xt_in(par), info->flags) ^ invert; |
| 83 | } | 84 | } |
| @@ -221,11 +221,11 @@ static int nat_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, · 220 unmodified lines | |||
| 221 | int ret; | 221 | int ret; |
| 222 | 222 | ||
| 223 | rtp_exp->tuple.dst.u.udp.port = htons(nated_port); | 223 | rtp_exp->tuple.dst.u.udp.port = htons(nated_port); |
| 224 | ret = nf_ct_expect_related(rtp_exp); | 224 | ret = nf_ct_expect_related(rtp_exp, 0); |
| 225 | if (ret == 0) { | 225 | if (ret == 0) { |
| 226 | rtcp_exp->tuple.dst.u.udp.port = | 226 | rtcp_exp->tuple.dst.u.udp.port = |
| 227 | htons(nated_port + 1); | 227 | htons(nated_port + 1); |
| 228 | ret = nf_ct_expect_related(rtcp_exp); | 228 | ret = nf_ct_expect_related(rtcp_exp, 0); |
| 229 | if (ret == 0) | 229 | if (ret == 0) |
| 230 | break; | 230 | break; |
| 231 | else if (ret == -EBUSY) { | 231 | else if (ret == -EBUSY) { |
| @@ -296,7 +296,7 @@ static int nat_t120(struct sk_buff *skb, struct nf_conn *ct, · 64 unmodified lines | |||
| 296 | int ret; | 296 | int ret; |
| 297 | 297 | ||
| 298 | exp->tuple.dst.u.tcp.port = htons(nated_port); | 298 | exp->tuple.dst.u.tcp.port = htons(nated_port); |
| 299 | ret = nf_ct_expect_related(exp); | 299 | ret = nf_ct_expect_related(exp, 0); |
| 300 | if (ret == 0) | 300 | if (ret == 0) |
| 301 | break; | 301 | break; |
| 302 | else if (ret != -EBUSY) { | 302 | else if (ret != -EBUSY) { |
| @@ -352,7 +352,7 @@ static int nat_h245(struct sk_buff *skb, struct nf_conn *ct, · 49 unmodified lines | |||
| 352 | int ret; | 352 | int ret; |
| 353 | 353 | ||
| 354 | exp->tuple.dst.u.tcp.port = htons(nated_port); | 354 | exp->tuple.dst.u.tcp.port = htons(nated_port); |
| 355 | ret = nf_ct_expect_related(exp); | 355 | ret = nf_ct_expect_related(exp, 0); |
| 356 | if (ret == 0) | 356 | if (ret == 0) |
| 357 | break; | 357 | break; |
| 358 | else if (ret != -EBUSY) { | 358 | else if (ret != -EBUSY) { |
| @@ -444,7 +444,7 @@ static int nat_q931(struct sk_buff *skb, struct nf_conn *ct, · 85 unmodified lines | |||
| 444 | int ret; | 444 | int ret; |
| 445 | 445 | ||
| 446 | exp->tuple.dst.u.tcp.port = htons(nated_port); | 446 | exp->tuple.dst.u.tcp.port = htons(nated_port); |
| 447 | ret = nf_ct_expect_related(exp); | 447 | ret = nf_ct_expect_related(exp, 0); |
| 448 | if (ret == 0) | 448 | if (ret == 0) |
| 449 | break; | 449 | break; |
| 450 | else if (ret != -EBUSY) { | 450 | else if (ret != -EBUSY) { |
| @@ -537,7 +537,7 @@ static int nat_callforwarding(struct sk_buff *skb, struct nf_conn *ct, · 86 unmodified lines | |||
| 537 | int ret; | 537 | int ret; |
| 538 | 538 | ||
| 539 | exp->tuple.dst.u.tcp.port = htons(nated_port); | 539 | exp->tuple.dst.u.tcp.port = htons(nated_port); |
| 540 | ret = nf_ct_expect_related(exp); | 540 | ret = nf_ct_expect_related(exp, 0); |
| 541 | if (ret == 0) | 541 | if (ret == 0) |
| 542 | break; | 542 | break; |
| 543 | else if (ret != -EBUSY) { | 543 | else if (ret != -EBUSY) { |
| @@ -36,6 +36,8 @@ synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) · 35 unmodified lines | |||
| 36 | opts.options |= XT_SYNPROXY_OPT_ECN; | 36 | opts.options |= XT_SYNPROXY_OPT_ECN; |
| 37 | 37 | ||
| 38 | opts.options &= info->options; | 38 | opts.options &= info->options; |
| 39 | opts.mss_encode = opts.mss; | ||
| 40 | opts.mss = info->mss; | ||
| 39 | if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) | 41 | if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) |
| 40 | synproxy_init_timestamp_cookie(info, &opts); | 42 | synproxy_init_timestamp_cookie(info, &opts); |
| 41 | else | 43 | else |
| @@ -55,7 +55,9 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb, · 54 unmodified lines | |||
| 55 | if (rpfilter_addr_linklocal(&iph->saddr)) { | 55 | if (rpfilter_addr_linklocal(&iph->saddr)) { |
| 56 | lookup_flags |= RT6_LOOKUP_F_IFACE; | 56 | lookup_flags |= RT6_LOOKUP_F_IFACE; |
| 57 | fl6.flowi6_oif = dev->ifindex; | 57 | fl6.flowi6_oif = dev->ifindex; |
| 58 | } else if ((flags & XT_RPFILTER_LOOSE) == 0) | 58 | /* Set flowi6_oif for vrf devices to lookup route in l3mdev domain. */ |
| 59 | } else if (netif_is_l3_master(dev) || netif_is_l3_slave(dev) || | ||
| 60 | (flags & XT_RPFILTER_LOOSE) == 0) | ||
| 59 | fl6.flowi6_oif = dev->ifindex; | 61 | fl6.flowi6_oif = dev->ifindex; |
| 60 | 62 | ||
| 61 | rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags); | 63 | rt = (void *)ip6_route_lookup(net, &fl6, skb, lookup_flags); |
| @@ -70,7 +72,9 @@ static bool rpfilter_lookup_reverse6(struct net *net, const struct sk_buff *skb, · 8 unmodified lines | |||
| 70 | goto out; | 72 | goto out; |
| 71 | } | 73 | } |
| 72 | 74 | ||
| 73 | if (rt->rt6i_idev->dev == dev || (flags & XT_RPFILTER_LOOSE)) | 75 | if (rt->rt6i_idev->dev == dev || |
| 76 | l3mdev_master_ifindex_rcu(rt->rt6i_idev->dev) == dev->ifindex || | ||
| 77 | (flags & XT_RPFILTER_LOOSE)) | ||
| 74 | ret = true; | 78 | ret = true; |
| 75 | out: | 79 | out: |
| 76 | ip6_rt_put(rt); | 80 | ip6_rt_put(rt); |
| @@ -223,8 +223,6 @@ config NF_CONNTRACK_FTP · 222 unmodified lines | |||
| 223 | of Network Address Translation on them. | 223 | of Network Address Translation on them. |
| 224 | 224 | ||
| 225 | This is FTP support on Layer 3 independent connection tracking. | 225 | This is FTP support on Layer 3 independent connection tracking. |
| 226 | Layer 3 independent connection tracking is experimental scheme | ||
| 227 | which generalize ip_conntrack to support other layer 3 protocols. | ||
| 228 | 226 | ||
| 229 | To compile it as a module, choose M here. If unsure, say N. | 227 | To compile it as a module, choose M here. If unsure, say N. |
| 230 | 228 | ||
| @@ -338,7 +336,7 @@ config NF_CONNTRACK_SIP · 107 unmodified lines | |||
| 338 | help | 336 | help |
| 339 | SIP is an application-layer control protocol that can establish, | 337 | SIP is an application-layer control protocol that can establish, |
| 340 | modify, and terminate multimedia sessions (conferences) such as | 338 | modify, and terminate multimedia sessions (conferences) such as |
| 341 | Internet telephony calls. With the ip_conntrack_sip and | 339 | Internet telephony calls. With the nf_conntrack_sip and |
| 342 | the nf_nat_sip modules you can support the protocol on a connection | 340 | the nf_nat_sip modules you can support the protocol on a connection |
| 343 | tracking/NATing firewall. | 341 | tracking/NATing firewall. |
| 344 | 342 | ||
| @@ -1313,7 +1311,7 @@ config NETFILTER_XT_MATCH_HELPER · 968 unmodified lines | |||
| 1313 | depends on NETFILTER_ADVANCED | 1311 | depends on NETFILTER_ADVANCED |
| 1314 | help | 1312 | help |
| 1315 | Helper matching allows you to match packets in dynamic connections | 1313 | Helper matching allows you to match packets in dynamic connections |
| 1316 | tracked by a conntrack-helper, ie. ip_conntrack_ftp | 1314 | tracked by a conntrack-helper, ie. nf_conntrack_ftp |
| 1317 | 1315 | ||
| 1318 | To compile it as a module, choose M here. If unsure, say Y. | 1316 | To compile it as a module, choose M here. If unsure, say Y. |
| 1319 | 1317 | ||
| @@ -231,7 +231,7 @@ void ip_vs_nfct_expect_related(struct sk_buff *skb, struct nf_conn *ct, · 230 unmodified lines | |||
| 231 | 231 | ||
| 232 | IP_VS_DBG_BUF(7, "%s: ct=%p, expect tuple=" FMT_TUPLE "\n", | 232 | IP_VS_DBG_BUF(7, "%s: ct=%p, expect tuple=" FMT_TUPLE "\n", |
| 233 | __func__, ct, ARG_TUPLE(&exp->tuple)); | 233 | __func__, ct, ARG_TUPLE(&exp->tuple)); |
| 234 | nf_ct_expect_related(exp); | 234 | nf_ct_expect_related(exp, 0); |
| 235 | nf_ct_expect_put(exp); | 235 | nf_ct_expect_put(exp); |
| 236 | } | 236 | } |
| 237 | EXPORT_SYMBOL(ip_vs_nfct_expect_related); | 237 | EXPORT_SYMBOL(ip_vs_nfct_expect_related); |
| @@ -159,7 +159,7 @@ static int amanda_help(struct sk_buff *skb, · 158 unmodified lines | |||
| 159 | if (nf_nat_amanda && ct->status & IPS_NAT_MASK) | 159 | if (nf_nat_amanda && ct->status & IPS_NAT_MASK) |
| 160 | ret = nf_nat_amanda(skb, ctinfo, protoff, | 160 | ret = nf_nat_amanda(skb, ctinfo, protoff, |
| 161 | off - dataoff, len, exp); | 161 | off - dataoff, len, exp); |
| 162 | else if (nf_ct_expect_related(exp) != 0) { | 162 | else if (nf_ct_expect_related(exp, 0) != 0) { |
| 163 | nf_ct_helper_log(skb, ct, "cannot add expectation"); | 163 | nf_ct_helper_log(skb, ct, "cannot add expectation"); |
| 164 | ret = NF_DROP; | 164 | ret = NF_DROP; |
| 165 | } | 165 | } |
| @@ -68,7 +68,7 @@ int nf_conntrack_broadcast_help(struct sk_buff *skb, · 67 unmodified lines | |||
| 68 | exp->class = NF_CT_EXPECT_CLASS_DEFAULT; | 68 | exp->class = NF_CT_EXPECT_CLASS_DEFAULT; |
| 69 | exp->helper = NULL; | 69 | exp->helper = NULL; |
| 70 | 70 | ||
| 71 | nf_ct_expect_related(exp); | 71 | nf_ct_expect_related(exp, 0); |
| 72 | nf_ct_expect_put(exp); | 72 | nf_ct_expect_put(exp); |
| 73 | 73 | ||
| 74 | nf_ct_refresh(ct, skb, timeout * HZ); | 74 | nf_ct_refresh(ct, skb, timeout * HZ); |
| @@ -1817,9 +1817,7 @@ EXPORT_SYMBOL_GPL(nf_ct_kill_acct); · 1816 unmodified lines | |||
| 1817 | #include <linux/netfilter/nfnetlink_conntrack.h> | 1817 | #include <linux/netfilter/nfnetlink_conntrack.h> |
| 1818 | #include <linux/mutex.h> | 1818 | #include <linux/mutex.h> |
| 1819 | 1819 | ||
| 1820 | /* Generic function for tcp/udp/sctp/dccp and alike. This needs to be | 1820 | /* Generic function for tcp/udp/sctp/dccp and alike. */ |
| 1821 | * in ip_conntrack_core, since we don't want the protocols to autoload | ||
| 1822 | * or depend on ctnetlink */ | ||
| 1823 | int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, | 1821 | int nf_ct_port_tuple_to_nlattr(struct sk_buff *skb, |
| 1824 | const struct nf_conntrack_tuple *tuple) | 1822 | const struct nf_conntrack_tuple *tuple) |
| 1825 | { | 1823 | { |
| @@ -249,13 +249,22 @@ static inline int expect_clash(const struct nf_conntrack_expect *a, · 248 unmodified lines | |||
| 249 | static inline int expect_matches(const struct nf_conntrack_expect *a, | 249 | static inline int expect_matches(const struct nf_conntrack_expect *a, |
| 250 | const struct nf_conntrack_expect *b) | 250 | const struct nf_conntrack_expect *b) |
| 251 | { | 251 | { |
| 252 | return a->master == b->master && | 252 | return nf_ct_tuple_equal(&a->tuple, &b->tuple) && |
| 253 | nf_ct_tuple_equal(&a->tuple, &b->tuple) && | ||
| 254 | nf_ct_tuple_mask_equal(&a->mask, &b->mask) && | 253 | nf_ct_tuple_mask_equal(&a->mask, &b->mask) && |
| 255 | net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) && | 254 | net_eq(nf_ct_net(a->master), nf_ct_net(b->master)) && |
| 256 | nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master)); | 255 | nf_ct_zone_equal_any(a->master, nf_ct_zone(b->master)); |
| 257 | } | 256 | } |
| 258 | 257 | ||
| 258 | static bool master_matches(const struct nf_conntrack_expect *a, | ||
| 259 | const struct nf_conntrack_expect *b, | ||
| 260 | unsigned int flags) | ||
| 261 | { | ||
| 262 | if (flags & NF_CT_EXP_F_SKIP_MASTER) | ||
| 263 | return true; | ||
| 264 | |||
| 265 | return a->master == b->master; | ||
| 266 | } | ||
| 267 | |||
| 259 | /* Generally a bad idea to call this: could have matched already. */ | 268 | /* Generally a bad idea to call this: could have matched already. */ |
| 260 | void nf_ct_unexpect_related(struct nf_conntrack_expect *exp) | 269 | void nf_ct_unexpect_related(struct nf_conntrack_expect *exp) |
| 261 | { | 270 | { |
| @@ -399,7 +408,8 @@ static void evict_oldest_expect(struct nf_conn *master, · 137 unmodified lines | |||
| 399 | nf_ct_remove_expect(last); | 408 | nf_ct_remove_expect(last); |
| 400 | } | 409 | } |
| 401 | 410 | ||
| 402 | static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) | 411 | static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect, |
| 412 | unsigned int flags) | ||
| 403 | { | 413 | { |
| 404 | const struct nf_conntrack_expect_policy *p; | 414 | const struct nf_conntrack_expect_policy *p; |
| 405 | struct nf_conntrack_expect *i; | 415 | struct nf_conntrack_expect *i; |
| @@ -417,8 +427,10 @@ static inline int __nf_ct_expect_check(struct nf_conntrack_expect *expect) · 11 unmodified lines | |||
| 417 | } | 427 | } |
| 418 | h = nf_ct_expect_dst_hash(net, &expect->tuple); | 428 | h = nf_ct_expect_dst_hash(net, &expect->tuple); |
| 419 | hlist_for_each_entry_safe(i, next, &nf_ct_expect_hash[h], hnode) { | 429 | hlist_for_each_entry_safe(i, next, &nf_ct_expect_hash[h], hnode) { |
| 420 | if (expect_matches(i, expect)) { | 430 | if (master_matches(i, expect, flags) && |
| 421 | if (i->class != expect->class) | 431 | expect_matches(i, expect)) { |
| 432 | if (i->class != expect->class || | ||
| 433 | i->master != expect->master) | ||
| 422 | return -EALREADY; | 434 | return -EALREADY; |
| 423 | 435 | ||
| 424 | if (nf_ct_remove_expect(i)) | 436 | if (nf_ct_remove_expect(i)) |
| @@ -453,12 +465,12 @@ out: · 28 unmodified lines | |||
| 453 | } | 465 | } |
| 454 | 466 | ||
| 455 | int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, | 467 | int nf_ct_expect_related_report(struct nf_conntrack_expect *expect, |
| 456 | u32 portid, int report) | 468 | u32 portid, int report, unsigned int flags) |
| 457 | { | 469 | { |
| 458 | int ret; | 470 | int ret; |
| 459 | 471 | ||
| 460 | spin_lock_bh(&nf_conntrack_expect_lock); | 472 | spin_lock_bh(&nf_conntrack_expect_lock); |
| 461 | ret = __nf_ct_expect_check(expect); | 473 | ret = __nf_ct_expect_check(expect, flags); |
| 462 | if (ret < 0) | 474 | if (ret < 0) |
| 463 | goto out; | 475 | goto out; |
| 464 | 476 | ||
| @@ -525,7 +525,7 @@ skip_nl_seq: · 524 unmodified lines | |||
| 525 | protoff, matchoff, matchlen, exp); | 525 | protoff, matchoff, matchlen, exp); |
| 526 | else { | 526 | else { |
| 527 | /* Can't expect this? Best to drop packet now. */ | 527 | /* Can't expect this? Best to drop packet now. */ |
| 528 | if (nf_ct_expect_related(exp) != 0) { | 528 | if (nf_ct_expect_related(exp, 0) != 0) { |
| 529 | nf_ct_helper_log(skb, ct, "cannot add expectation"); | 529 | nf_ct_helper_log(skb, ct, "cannot add expectation"); |
| 530 | ret = NF_DROP; | 530 | ret = NF_DROP; |
| 531 | } else | 531 | } else |
| @@ -1,11 +1,10 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * ip_conntrack_helper_h323_asn1.c - BER and PER decoding library for H.323 | 3 | * BER and PER decoding library for H.323 conntrack/NAT module. |
| 4 | * conntrack/NAT module. | ||
| 5 | * | 4 | * |
| 6 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> | 5 | * Copyright (c) 2006 by Jing Min Zhao <zhaojingmin@users.sourceforge.net> |
| 7 | * | 6 | * |
| 8 | * See ip_conntrack_helper_h323_asn1.h for details. | 7 | * See nf_conntrack_helper_h323_asn1.h for details. |
| 9 | */ | 8 | */ |
| 10 | 9 | ||
| 11 | #ifdef __KERNEL__ | 10 | #ifdef __KERNEL__ |
| @@ -305,8 +305,8 @@ static int expect_rtp_rtcp(struct sk_buff *skb, struct nf_conn *ct, · 304 unmodified lines | |||
| 305 | ret = nat_rtp_rtcp(skb, ct, ctinfo, protoff, data, dataoff, | 305 | ret = nat_rtp_rtcp(skb, ct, ctinfo, protoff, data, dataoff, |
| 306 | taddr, port, rtp_port, rtp_exp, rtcp_exp); | 306 | taddr, port, rtp_port, rtp_exp, rtcp_exp); |
| 307 | } else { /* Conntrack only */ | 307 | } else { /* Conntrack only */ |
| 308 | if (nf_ct_expect_related(rtp_exp) == 0) { | 308 | if (nf_ct_expect_related(rtp_exp, 0) == 0) { |
| 309 | if (nf_ct_expect_related(rtcp_exp) == 0) { | 309 | if (nf_ct_expect_related(rtcp_exp, 0) == 0) { |
| 310 | pr_debug("nf_ct_h323: expect RTP "); | 310 | pr_debug("nf_ct_h323: expect RTP "); |
| 311 | nf_ct_dump_tuple(&rtp_exp->tuple); | 311 | nf_ct_dump_tuple(&rtp_exp->tuple); |
| 312 | pr_debug("nf_ct_h323: expect RTCP "); | 312 | pr_debug("nf_ct_h323: expect RTCP "); |
| @@ -364,7 +364,7 @@ static int expect_t120(struct sk_buff *skb, · 51 unmodified lines | |||
| 364 | ret = nat_t120(skb, ct, ctinfo, protoff, data, dataoff, taddr, | 364 | ret = nat_t120(skb, ct, ctinfo, protoff, data, dataoff, taddr, |
| 365 | port, exp); | 365 | port, exp); |
| 366 | } else { /* Conntrack only */ | 366 | } else { /* Conntrack only */ |
| 367 | if (nf_ct_expect_related(exp) == 0) { | 367 | if (nf_ct_expect_related(exp, 0) == 0) { |
| 368 | pr_debug("nf_ct_h323: expect T.120 "); | 368 | pr_debug("nf_ct_h323: expect T.120 "); |
| 369 | nf_ct_dump_tuple(&exp->tuple); | 369 | nf_ct_dump_tuple(&exp->tuple); |
| 370 | } else | 370 | } else |
| @@ -701,7 +701,7 @@ static int expect_h245(struct sk_buff *skb, struct nf_conn *ct, · 330 unmodified lines | |||
| 701 | ret = nat_h245(skb, ct, ctinfo, protoff, data, dataoff, taddr, | 701 | ret = nat_h245(skb, ct, ctinfo, protoff, data, dataoff, taddr, |
| 702 | port, exp); | 702 | port, exp); |
| 703 | } else { /* Conntrack only */ | 703 | } else { /* Conntrack only */ |
| 704 | if (nf_ct_expect_related(exp) == 0) { | 704 | if (nf_ct_expect_related(exp, 0) == 0) { |
| 705 | pr_debug("nf_ct_q931: expect H.245 "); | 705 | pr_debug("nf_ct_q931: expect H.245 "); |
| 706 | nf_ct_dump_tuple(&exp->tuple); | 706 | nf_ct_dump_tuple(&exp->tuple); |
| 707 | } else | 707 | } else |
| @@ -825,7 +825,7 @@ static int expect_callforwarding(struct sk_buff *skb, · 117 unmodified lines | |||
| 825 | protoff, data, dataoff, | 825 | protoff, data, dataoff, |
| 826 | taddr, port, exp); | 826 | taddr, port, exp); |
| 827 | } else { /* Conntrack only */ | 827 | } else { /* Conntrack only */ |
| 828 | if (nf_ct_expect_related(exp) == 0) { | 828 | if (nf_ct_expect_related(exp, 0) == 0) { |
| 829 | pr_debug("nf_ct_q931: expect Call Forwarding "); | 829 | pr_debug("nf_ct_q931: expect Call Forwarding "); |
| 830 | nf_ct_dump_tuple(&exp->tuple); | 830 | nf_ct_dump_tuple(&exp->tuple); |
| 831 | } else | 831 | } else |
| @@ -1284,7 +1284,7 @@ static int expect_q931(struct sk_buff *skb, struct nf_conn *ct, · 452 unmodified lines | |||
| 1284 | ret = nat_q931(skb, ct, ctinfo, protoff, data, | 1284 | ret = nat_q931(skb, ct, ctinfo, protoff, data, |
| 1285 | taddr, i, port, exp); | 1285 | taddr, i, port, exp); |
| 1286 | } else { /* Conntrack only */ | 1286 | } else { /* Conntrack only */ |
| 1287 | if (nf_ct_expect_related(exp) == 0) { | 1287 | if (nf_ct_expect_related(exp, 0) == 0) { |
| 1288 | pr_debug("nf_ct_ras: expect Q.931 "); | 1288 | pr_debug("nf_ct_ras: expect Q.931 "); |
| 1289 | nf_ct_dump_tuple(&exp->tuple); | 1289 | nf_ct_dump_tuple(&exp->tuple); |
| 1290 | 1290 | ||
| @@ -1349,7 +1349,7 @@ static int process_gcf(struct sk_buff *skb, struct nf_conn *ct, · 58 unmodified lines | |||
| 1349 | IPPROTO_UDP, NULL, &port); | 1349 | IPPROTO_UDP, NULL, &port); |
| 1350 | exp->helper = nf_conntrack_helper_ras; | 1350 | exp->helper = nf_conntrack_helper_ras; |
| 1351 | 1351 | ||
| 1352 | if (nf_ct_expect_related(exp) == 0) { | 1352 | if (nf_ct_expect_related(exp, 0) == 0) { |
| 1353 | pr_debug("nf_ct_ras: expect RAS "); | 1353 | pr_debug("nf_ct_ras: expect RAS "); |
| 1354 | nf_ct_dump_tuple(&exp->tuple); | 1354 | nf_ct_dump_tuple(&exp->tuple); |
| 1355 | } else | 1355 | } else |
| @@ -1561,7 +1561,7 @@ static int process_acf(struct sk_buff *skb, struct nf_conn *ct, · 205 unmodified lines | |||
| 1561 | exp->flags = NF_CT_EXPECT_PERMANENT; | 1561 | exp->flags = NF_CT_EXPECT_PERMANENT; |
| 1562 | exp->helper = nf_conntrack_helper_q931; | 1562 | exp->helper = nf_conntrack_helper_q931; |
| 1563 | 1563 | ||
| 1564 | if (nf_ct_expect_related(exp) == 0) { | 1564 | if (nf_ct_expect_related(exp, 0) == 0) { |
| 1565 | pr_debug("nf_ct_ras: expect Q.931 "); | 1565 | pr_debug("nf_ct_ras: expect Q.931 "); |
| 1566 | nf_ct_dump_tuple(&exp->tuple); | 1566 | nf_ct_dump_tuple(&exp->tuple); |
| 1567 | } else | 1567 | } else |
| @@ -1615,7 +1615,7 @@ static int process_lcf(struct sk_buff *skb, struct nf_conn *ct, · 47 unmodified lines | |||
| 1615 | exp->flags = NF_CT_EXPECT_PERMANENT; | 1615 | exp->flags = NF_CT_EXPECT_PERMANENT; |
| 1616 | exp->helper = nf_conntrack_helper_q931; | 1616 | exp->helper = nf_conntrack_helper_q931; |
| 1617 | 1617 | ||
| 1618 | if (nf_ct_expect_related(exp) == 0) { | 1618 | if (nf_ct_expect_related(exp, 0) == 0) { |
| 1619 | pr_debug("nf_ct_ras: expect Q.931 "); | 1619 | pr_debug("nf_ct_ras: expect Q.931 "); |
| 1620 | nf_ct_dump_tuple(&exp->tuple); | 1620 | nf_ct_dump_tuple(&exp->tuple); |
| 1621 | } else | 1621 | } else |
| @@ -213,7 +213,7 @@ static int help(struct sk_buff *skb, unsigned int protoff, · 212 unmodified lines | |||
| 213 | addr_beg_p - ib_ptr, | 213 | addr_beg_p - ib_ptr, |
| 214 | addr_end_p - addr_beg_p, | 214 | addr_end_p - addr_beg_p, |
| 215 | exp); | 215 | exp); |
| 216 | else if (nf_ct_expect_related(exp) != 0) { | 216 | else if (nf_ct_expect_related(exp, 0) != 0) { |
| 217 | nf_ct_helper_log(skb, ct, | 217 | nf_ct_helper_log(skb, ct, |
| 218 | "cannot add expectation"); | 218 | "cannot add expectation"); |
| 219 | ret = NF_DROP; | 219 | ret = NF_DROP; |
| @@ -2616,7 +2616,7 @@ ctnetlink_glue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, · 2615 unmodified lines | |||
| 2616 | if (IS_ERR(exp)) | 2616 | if (IS_ERR(exp)) |
| 2617 | return PTR_ERR(exp); | 2617 | return PTR_ERR(exp); |
| 2618 | 2618 | ||
| 2619 | err = nf_ct_expect_related_report(exp, portid, report); | 2619 | err = nf_ct_expect_related_report(exp, portid, report, 0); |
| 2620 | nf_ct_expect_put(exp); | 2620 | nf_ct_expect_put(exp); |
| 2621 | return err; | 2621 | return err; |
| 2622 | } | 2622 | } |
| @@ -3367,7 +3367,7 @@ ctnetlink_create_expect(struct net *net, · 744 unmodified lines | |||
| 3367 | goto err_rcu; | 3367 | goto err_rcu; |
| 3368 | } | 3368 | } |
| 3369 | 3369 | ||
| 3370 | err = nf_ct_expect_related_report(exp, portid, report); | 3370 | err = nf_ct_expect_related_report(exp, portid, report, 0); |
| 3371 | nf_ct_expect_put(exp); | 3371 | nf_ct_expect_put(exp); |
| 3372 | err_rcu: | 3372 | err_rcu: |
| 3373 | rcu_read_unlock(); | 3373 | rcu_read_unlock(); |
| @@ -234,9 +234,9 @@ static int exp_gre(struct nf_conn *ct, __be16 callid, __be16 peer_callid) · 233 unmodified lines | |||
| 234 | nf_nat_pptp_exp_gre = rcu_dereference(nf_nat_pptp_hook_exp_gre); | 234 | nf_nat_pptp_exp_gre = rcu_dereference(nf_nat_pptp_hook_exp_gre); |
| 235 | if (nf_nat_pptp_exp_gre && ct->status & IPS_NAT_MASK) | 235 | if (nf_nat_pptp_exp_gre && ct->status & IPS_NAT_MASK) |
| 236 | nf_nat_pptp_exp_gre(exp_orig, exp_reply); | 236 | nf_nat_pptp_exp_gre(exp_orig, exp_reply); |
| 237 | if (nf_ct_expect_related(exp_orig) != 0) | 237 | if (nf_ct_expect_related(exp_orig, 0) != 0) |
| 238 | goto out_put_both; | 238 | goto out_put_both; |
| 239 | if (nf_ct_expect_related(exp_reply) != 0) | 239 | if (nf_ct_expect_related(exp_reply, 0) != 0) |
| 240 | goto out_unexpect_orig; | 240 | goto out_unexpect_orig; |
| 241 | 241 | ||
| 242 | /* Add GRE keymap entries */ | 242 | /* Add GRE keymap entries */ |
| @@ -1,7 +1,5 @@ | |||
| 1 | // SPDX-License-Identifier: GPL-2.0-only | 1 | // SPDX-License-Identifier: GPL-2.0-only |
| 2 | /* | 2 | /* |
| 3 | * ip_conntrack_proto_gre.c - Version 3.0 | ||
| 4 | * | ||
| 5 | * Connection tracking protocol helper module for GRE. | 3 | * Connection tracking protocol helper module for GRE. |
| 6 | * | 4 | * |
| 7 | * GRE is a generic encapsulation protocol, which is generally not very | 5 | * GRE is a generic encapsulation protocol, which is generally not very |
| @@ -215,7 +215,7 @@ int nf_conntrack_icmpv4_error(struct nf_conn *tmpl, · 214 unmodified lines | |||
| 215 | return -NF_ACCEPT; | 215 | return -NF_ACCEPT; |
| 216 | } | 216 | } |
| 217 | 217 | ||
| 218 | /* See ip_conntrack_proto_tcp.c */ | 218 | /* See nf_conntrack_proto_tcp.c */ |
| 219 | if (state->net->ct.sysctl_checksum && | 219 | if (state->net->ct.sysctl_checksum && |
| 220 | state->hook == NF_INET_PRE_ROUTING && | 220 | state->hook == NF_INET_PRE_ROUTING && |
| 221 | nf_ip_checksum(skb, state->hook, dataoff, IPPROTO_ICMP)) { | 221 | nf_ip_checksum(skb, state->hook, dataoff, IPPROTO_ICMP)) { |
| @@ -472,6 +472,7 @@ static bool tcp_in_window(const struct nf_conn *ct, · 471 unmodified lines | |||
| 472 | struct ip_ct_tcp_state *receiver = &state->seen[!dir]; | 472 | struct ip_ct_tcp_state *receiver = &state->seen[!dir]; |
| 473 | const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; | 473 | const struct nf_conntrack_tuple *tuple = &ct->tuplehash[dir].tuple; |
| 474 | __u32 seq, ack, sack, end, win, swin; | 474 | __u32 seq, ack, sack, end, win, swin; |
| 475 | u16 win_raw; | ||
| 475 | s32 receiver_offset; | 476 | s32 receiver_offset; |
| 476 | bool res, in_recv_win; | 477 | bool res, in_recv_win; |
| 477 | 478 | ||
| @@ -480,7 +481,8 @@ static bool tcp_in_window(const struct nf_conn *ct, · 2 unmodified lines | |||
| 480 | */ | 481 | */ |
| 481 | seq = ntohl(tcph->seq); | 482 | seq = ntohl(tcph->seq); |
| 482 | ack = sack = ntohl(tcph->ack_seq); | 483 | ack = sack = ntohl(tcph->ack_seq); |
| 483 | win = ntohs(tcph->window); | 484 | win_raw = ntohs(tcph->window); |
| 485 | win = win_raw; | ||
| 484 | end = segment_seq_plus_len(seq, skb->len, dataoff, tcph); | 486 | end = segment_seq_plus_len(seq, skb->len, dataoff, tcph); |
| 485 | 487 | ||
| 486 | if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) | 488 | if (receiver->flags & IP_CT_TCP_FLAG_SACK_PERM) |
| @@ -655,14 +657,14 @@ static bool tcp_in_window(const struct nf_conn *ct, · 168 unmodified lines | |||
| 655 | && state->last_seq == seq | 657 | && state->last_seq == seq |
| 656 | && state->last_ack == ack | 658 | && state->last_ack == ack |
| 657 | && state->last_end == end | 659 | && state->last_end == end |
| 658 | && state->last_win == win) | 660 | && state->last_win == win_raw) |
| 659 | state->retrans++; | 661 | state->retrans++; |
| 660 | else { | 662 | else { |
| 661 | state->last_dir = dir; | 663 | state->last_dir = dir; |
| 662 | state->last_seq = seq; | 664 | state->last_seq = seq; |
| 663 | state->last_ack = ack; | 665 | state->last_ack = ack; |
| 664 | state->last_end = end; | 666 | state->last_end = end; |
| 665 | state->last_win = win; | 667 | state->last_win = win_raw; |
| 666 | state->retrans = 0; | 668 | state->retrans = 0; |
| 667 | } | 669 | } |
| 668 | } | 670 | } |
| @@ -153,7 +153,7 @@ static int help(struct sk_buff *skb, · 152 unmodified lines | |||
| 153 | nf_ct_dump_tuple(&exp->tuple); | 153 | nf_ct_dump_tuple(&exp->tuple); |
| 154 | 154 | ||
| 155 | /* Can't expect this? Best to drop packet now. */ | 155 | /* Can't expect this? Best to drop packet now. */ |
| 156 | if (nf_ct_expect_related(exp) != 0) { | 156 | if (nf_ct_expect_related(exp, 0) != 0) { |
| 157 | nf_ct_helper_log(skb, ct, "cannot add expectation"); | 157 | nf_ct_helper_log(skb, ct, "cannot add expectation"); |
| 158 | ret = NF_DROP; | 158 | ret = NF_DROP; |
| 159 | } | 159 | } |
| @@ -977,11 +977,15 @@ static int set_expected_rtp_rtcp(struct sk_buff *skb, unsigned int protoff, · 976 unmodified lines | |||
| 977 | /* -EALREADY handling works around end-points that send | 977 | /* -EALREADY handling works around end-points that send |
| 978 | * SDP messages with identical port but different media type, | 978 | * SDP messages with identical port but different media type, |
| 979 | * we pretend expectation was set up. | 979 | * we pretend expectation was set up. |
| 980 | * It also works in the case that SDP messages are sent with | ||
| 981 | * identical expect tuples but for different master conntracks. | ||
| 980 | */ | 982 | */ |
| 981 | int errp = nf_ct_expect_related(rtp_exp); | 983 | int errp = nf_ct_expect_related(rtp_exp, |
| 984 | NF_CT_EXP_F_SKIP_MASTER); | ||
| 982 | 985 | ||
| 983 | if (errp == 0 || errp == -EALREADY) { | 986 | if (errp == 0 || errp == -EALREADY) { |
| 984 | int errcp = nf_ct_expect_related(rtcp_exp); | 987 | int errcp = nf_ct_expect_related(rtcp_exp, |
| 988 | NF_CT_EXP_F_SKIP_MASTER); | ||
| 985 | 989 | ||
| 986 | if (errcp == 0 || errcp == -EALREADY) | 990 | if (errcp == 0 || errcp == -EALREADY) |
| 987 | ret = NF_ACCEPT; | 991 | ret = NF_ACCEPT; |
| @@ -1296,7 +1300,7 @@ static int process_register_request(struct sk_buff *skb, unsigned int protoff, · 308 unmodified lines | |||
| 1296 | ret = hooks->expect(skb, protoff, dataoff, dptr, datalen, | 1300 | ret = hooks->expect(skb, protoff, dataoff, dptr, datalen, |
| 1297 | exp, matchoff, matchlen); | 1301 | exp, matchoff, matchlen); |
| 1298 | else { | 1302 | else { |
| 1299 | if (nf_ct_expect_related(exp) != 0) { | 1303 | if (nf_ct_expect_related(exp, 0) != 0) { |
| 1300 | nf_ct_helper_log(skb, ct, "cannot add expectation"); | 1304 | nf_ct_helper_log(skb, ct, "cannot add expectation"); |
| 1301 | ret = NF_DROP; | 1305 | ret = NF_DROP; |
| 1302 | } else | 1306 | } else |
| @@ -78,7 +78,7 @@ static int tftp_help(struct sk_buff *skb, · 77 unmodified lines | |||
| 78 | nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook); | 78 | nf_nat_tftp = rcu_dereference(nf_nat_tftp_hook); |
| 79 | if (nf_nat_tftp && ct->status & IPS_NAT_MASK) | 79 | if (nf_nat_tftp && ct->status & IPS_NAT_MASK) |
| 80 | ret = nf_nat_tftp(skb, ctinfo, exp); | 80 | ret = nf_nat_tftp(skb, ctinfo, exp); |
| 81 | else if (nf_ct_expect_related(exp) != 0) { | 81 | else if (nf_ct_expect_related(exp, 0) != 0) { |
| 82 | nf_ct_helper_log(skb, ct, "cannot add expectation"); | 82 | nf_ct_helper_log(skb, ct, "cannot add expectation"); |
| 83 | ret = NF_DROP; | 83 | ret = NF_DROP; |
| 84 | } | 84 | } |
| @@ -48,7 +48,7 @@ static unsigned int help(struct sk_buff *skb, · 47 unmodified lines | |||
| 48 | int res; | 48 | int res; |
| 49 | 49 | ||
| 50 | exp->tuple.dst.u.tcp.port = htons(port); | 50 | exp->tuple.dst.u.tcp.port = htons(port); |
| 51 | res = nf_ct_expect_related(exp); | 51 | res = nf_ct_expect_related(exp, 0); |
| 52 | if (res == 0) | 52 | if (res == 0) |
| 53 | break; | 53 | break; |
| 54 | else if (res != -EBUSY) { | 54 | else if (res != -EBUSY) { |
| @@ -519,7 +519,7 @@ another_round: · 518 unmodified lines | |||
| 519 | * and NF_INET_LOCAL_OUT, we change the destination to map into the | 519 | * and NF_INET_LOCAL_OUT, we change the destination to map into the |
| 520 | * range. It might not be possible to get a unique tuple, but we try. | 520 | * range. It might not be possible to get a unique tuple, but we try. |
| 521 | * At worst (or if we race), we will end up with a final duplicate in | 521 | * At worst (or if we race), we will end up with a final duplicate in |
| 522 | * __ip_conntrack_confirm and drop the packet. */ | 522 | * __nf_conntrack_confirm and drop the packet. */ |
| 523 | static void | 523 | static void |
| 524 | get_unique_tuple(struct nf_conntrack_tuple *tuple, | 524 | get_unique_tuple(struct nf_conntrack_tuple *tuple, |
| 525 | const struct nf_conntrack_tuple *orig_tuple, | 525 | const struct nf_conntrack_tuple *orig_tuple, |
| @@ -91,7 +91,7 @@ static unsigned int nf_nat_ftp(struct sk_buff *skb, · 90 unmodified lines | |||
| 91 | int ret; | 91 | int ret; |
| 92 | 92 | ||
| 93 | exp->tuple.dst.u.tcp.port = htons(port); | 93 | exp->tuple.dst.u.tcp.port = htons(port); |
| 94 | ret = nf_ct_expect_related(exp); | 94 | ret = nf_ct_expect_related(exp, 0); |
| 95 | if (ret == 0) | 95 | if (ret == 0) |
| 96 | break; | 96 | break; |
| 97 | else if (ret != -EBUSY) { | 97 | else if (ret != -EBUSY) { |
| @@ -53,7 +53,7 @@ static unsigned int help(struct sk_buff *skb, · 52 unmodified lines | |||
| 53 | int ret; | 53 | int ret; |
| 54 | 54 | ||
| 55 | exp->tuple.dst.u.tcp.port = htons(port); | 55 | exp->tuple.dst.u.tcp.port = htons(port); |
| 56 | ret = nf_ct_expect_related(exp); | 56 | ret = nf_ct_expect_related(exp, 0); |
| 57 | if (ret == 0) | 57 | if (ret == 0) |
| 58 | break; | 58 | break; |
| 59 | else if (ret != -EBUSY) { | 59 | else if (ret != -EBUSY) { |
| @@ -414,7 +414,7 @@ static unsigned int nf_nat_sip_expect(struct sk_buff *skb, unsigned int protoff, · 413 unmodified lines | |||
| 414 | int ret; | 414 | int ret; |
| 415 | 415 | ||
| 416 | exp->tuple.dst.u.udp.port = htons(port); | 416 | exp->tuple.dst.u.udp.port = htons(port); |
| 417 | ret = nf_ct_expect_related(exp); | 417 | ret = nf_ct_expect_related(exp, NF_CT_EXP_F_SKIP_MASTER); |
| 418 | if (ret == 0) | 418 | if (ret == 0) |
| 419 | break; | 419 | break; |
| 420 | else if (ret != -EBUSY) { | 420 | else if (ret != -EBUSY) { |
| @@ -607,7 +607,8 @@ static unsigned int nf_nat_sdp_media(struct sk_buff *skb, unsigned int protoff, · 186 unmodified lines | |||
| 607 | int ret; | 607 | int ret; |
| 608 | 608 | ||
| 609 | rtp_exp->tuple.dst.u.udp.port = htons(port); | 609 | rtp_exp->tuple.dst.u.udp.port = htons(port); |
| 610 | ret = nf_ct_expect_related(rtp_exp); | 610 | ret = nf_ct_expect_related(rtp_exp, |
| 611 | NF_CT_EXP_F_SKIP_MASTER); | ||
| 611 | if (ret == -EBUSY) | 612 | if (ret == -EBUSY) |
| 612 | continue; | 613 | continue; |
| 613 | else if (ret < 0) { | 614 | else if (ret < 0) { |
| @@ -615,7 +616,8 @@ static unsigned int nf_nat_sdp_media(struct sk_buff *skb, unsigned int protoff, · 1 unmodified line | |||
| 615 | break; | 616 | break; |
| 616 | } | 617 | } |
| 617 | rtcp_exp->tuple.dst.u.udp.port = htons(port + 1); | 618 | rtcp_exp->tuple.dst.u.udp.port = htons(port + 1); |
| 618 | ret = nf_ct_expect_related(rtcp_exp); | 619 | ret = nf_ct_expect_related(rtcp_exp, |
| 620 | NF_CT_EXP_F_SKIP_MASTER); | ||
| 619 | if (ret == 0) | 621 | if (ret == 0) |
| 620 | break; | 622 | break; |
| 621 | else if (ret == -EBUSY) { | 623 | else if (ret == -EBUSY) { |
| @@ -30,7 +30,7 @@ static unsigned int help(struct sk_buff *skb, · 29 unmodified lines | |||
| 30 | = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port; | 30 | = ct->tuplehash[IP_CT_DIR_ORIGINAL].tuple.src.u.udp.port; |
| 31 | exp->dir = IP_CT_DIR_REPLY; | 31 | exp->dir = IP_CT_DIR_REPLY; |
| 32 | exp->expectfn = nf_nat_follow_master; | 32 | exp->expectfn = nf_nat_follow_master; |
| 33 | if (nf_ct_expect_related(exp) != 0) { | 33 | if (nf_ct_expect_related(exp, 0) != 0) { |
| 34 | nf_ct_helper_log(skb, exp->master, "cannot add expectation"); | 34 | nf_ct_helper_log(skb, exp->master, "cannot add expectation"); |
| 35 | return NF_DROP; | 35 | return NF_DROP; |
| 36 | } | 36 | } |
| @@ -470,7 +470,7 @@ synproxy_send_client_synack(struct net *net, · 469 unmodified lines | |||
| 470 | struct iphdr *iph, *niph; | 470 | struct iphdr *iph, *niph; |
| 471 | struct tcphdr *nth; | 471 | struct tcphdr *nth; |
| 472 | unsigned int tcp_hdr_size; | 472 | unsigned int tcp_hdr_size; |
| 473 | u16 mss = opts->mss; | 473 | u16 mss = opts->mss_encode; |
| 474 | 474 | ||
| 475 | iph = ip_hdr(skb); | 475 | iph = ip_hdr(skb); |
| 476 | 476 | ||
| @@ -687,7 +687,7 @@ ipv4_synproxy_hook(void *priv, struct sk_buff *skb, · 210 unmodified lines | |||
| 687 | state = &ct->proto.tcp; | 687 | state = &ct->proto.tcp; |
| 688 | switch (state->state) { | 688 | switch (state->state) { |
| 689 | case TCP_CONNTRACK_CLOSE: | 689 | case TCP_CONNTRACK_CLOSE: |
| 690 | if (th->rst && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { | 690 | if (th->rst && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { |
| 691 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - | 691 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - |
| 692 | ntohl(th->seq) + 1); | 692 | ntohl(th->seq) + 1); |
| 693 | break; | 693 | break; |
| @@ -884,7 +884,7 @@ synproxy_send_client_synack_ipv6(struct net *net, · 190 unmodified lines | |||
| 884 | struct ipv6hdr *iph, *niph; | 884 | struct ipv6hdr *iph, *niph; |
| 885 | struct tcphdr *nth; | 885 | struct tcphdr *nth; |
| 886 | unsigned int tcp_hdr_size; | 886 | unsigned int tcp_hdr_size; |
| 887 | u16 mss = opts->mss; | 887 | u16 mss = opts->mss_encode; |
| 888 | 888 | ||
| 889 | iph = ipv6_hdr(skb); | 889 | iph = ipv6_hdr(skb); |
| 890 | 890 | ||
| @@ -1111,7 +1111,7 @@ ipv6_synproxy_hook(void *priv, struct sk_buff *skb, · 220 unmodified lines | |||
| 1111 | state = &ct->proto.tcp; | 1111 | state = &ct->proto.tcp; |
| 1112 | switch (state->state) { | 1112 | switch (state->state) { |
| 1113 | case TCP_CONNTRACK_CLOSE: | 1113 | case TCP_CONNTRACK_CLOSE: |
| 1114 | if (th->rst && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { | 1114 | if (th->rst && CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) { |
| 1115 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - | 1115 | nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - |
| 1116 | ntohl(th->seq) + 1); | 1116 | ntohl(th->seq) + 1); |
| 1117 | break; | 1117 | break; |
| @@ -1900,6 +1900,8 @@ static int nf_tables_newchain(struct net *net, struct sock *nlsk, · 1899 unmodified lines | |||
| 1900 | 1900 | ||
| 1901 | if (nla[NFTA_CHAIN_FLAGS]) | 1901 | if (nla[NFTA_CHAIN_FLAGS]) |
| 1902 | flags = ntohl(nla_get_be32(nla[NFTA_CHAIN_FLAGS])); | 1902 | flags = ntohl(nla_get_be32(nla[NFTA_CHAIN_FLAGS])); |
| 1903 | else if (chain) | ||
| 1904 | flags = chain->flags; | ||
| 1903 | 1905 | ||
| 1904 | nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); | 1906 | nft_ctx_init(&ctx, net, skb, nlh, family, table, chain, nla); |
| 1905 | 1907 | ||
| @@ -578,7 +578,7 @@ static int nfnetlink_bind(struct net *net, int group) · 577 unmodified lines | |||
| 578 | ss = nfnetlink_get_subsys(type << 8); | 578 | ss = nfnetlink_get_subsys(type << 8); |
| 579 | rcu_read_unlock(); | 579 | rcu_read_unlock(); |
| 580 | if (!ss) | 580 | if (!ss) |
| 581 | request_module("nfnetlink-subsys-%d", type); | 581 | request_module_nowait("nfnetlink-subsys-%d", type); |
| 582 | return 0; | 582 | return 0; |
| 583 | } | 583 | } |
| 584 | #endif | 584 | #endif |
| @@ -193,7 +193,7 @@ static inline void nft_chain_filter_inet_init(void) {} · 192 unmodified lines | |||
| 193 | static inline void nft_chain_filter_inet_fini(void) {} | 193 | static inline void nft_chain_filter_inet_fini(void) {} |
| 194 | #endif /* CONFIG_NF_TABLES_IPV6 */ | 194 | #endif /* CONFIG_NF_TABLES_IPV6 */ |
| 195 | 195 | ||
| 196 | #ifdef CONFIG_NF_TABLES_BRIDGE | 196 | #if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE) |
| 197 | static unsigned int | 197 | static unsigned int |
| 198 | nft_do_chain_bridge(void *priv, | 198 | nft_do_chain_bridge(void *priv, |
| 199 | struct sk_buff *skb, | 199 | struct sk_buff *skb, |
| @@ -142,3 +142,6 @@ MODULE_ALIAS_NFT_CHAIN(AF_INET, "nat"); · 141 unmodified lines | |||
| 142 | #ifdef CONFIG_NF_TABLES_IPV6 | 142 | #ifdef CONFIG_NF_TABLES_IPV6 |
| 143 | MODULE_ALIAS_NFT_CHAIN(AF_INET6, "nat"); | 143 | MODULE_ALIAS_NFT_CHAIN(AF_INET6, "nat"); |
| 144 | #endif | 144 | #endif |
| 145 | #ifdef CONFIG_NF_TABLES_INET | ||
| 146 | MODULE_ALIAS_NFT_CHAIN(1, "nat"); /* NFPROTO_INET */ | ||
| 147 | #endif | ||
| @@ -1252,7 +1252,7 @@ static void nft_ct_expect_obj_eval(struct nft_object *obj, · 1251 unmodified lines | |||
| 1252 | priv->l4proto, NULL, &priv->dport); | 1252 | priv->l4proto, NULL, &priv->dport); |
| 1253 | exp->timeout.expires = jiffies + priv->timeout * HZ; | 1253 | exp->timeout.expires = jiffies + priv->timeout * HZ; |
| 1254 | 1254 | ||
| 1255 | if (nf_ct_expect_related(exp) != 0) | 1255 | if (nf_ct_expect_related(exp, 0) != 0) |
| 1256 | regs->verdict.code = NF_DROP; | 1256 | regs->verdict.code = NF_DROP; |
| 1257 | } | 1257 | } |
| 1258 | 1258 | ||
| @@ -129,7 +129,7 @@ static int nft_symhash_init(const struct nft_ctx *ctx, · 128 unmodified lines | |||
| 129 | priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]); | 129 | priv->dreg = nft_parse_register(tb[NFTA_HASH_DREG]); |
| 130 | 130 | ||
| 131 | priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS])); | 131 | priv->modulus = ntohl(nla_get_be32(tb[NFTA_HASH_MODULUS])); |
| 132 | if (priv->modulus <= 1) | 132 | if (priv->modulus < 1) |
| 133 | return -ERANGE; | 133 | return -ERANGE; |
| 134 | 134 | ||
| 135 | if (priv->offset + priv->modulus - 1 < priv->offset) | 135 | if (priv->offset + priv->modulus - 1 < priv->offset) |
| @@ -546,7 +546,7 @@ nft_meta_select_ops(const struct nft_ctx *ctx, · 545 unmodified lines | |||
| 546 | if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG]) | 546 | if (tb[NFTA_META_DREG] && tb[NFTA_META_SREG]) |
| 547 | return ERR_PTR(-EINVAL); | 547 | return ERR_PTR(-EINVAL); |
| 548 | 548 | ||
| 549 | #ifdef CONFIG_NF_TABLES_BRIDGE | 549 | #if IS_ENABLED(CONFIG_NF_TABLES_BRIDGE) && IS_MODULE(CONFIG_NFT_BRIDGE_META) |
| 550 | if (ctx->family == NFPROTO_BRIDGE) | 550 | if (ctx->family == NFPROTO_BRIDGE) |
| 551 | return ERR_PTR(-EAGAIN); | 551 | return ERR_PTR(-EAGAIN); |
| 552 | #endif | 552 | #endif |
| @@ -291,4 +291,4 @@ module_exit(nft_redir_module_exit); · 290 unmodified lines | |||
| 291 | 291 | ||
| 292 | MODULE_LICENSE("GPL"); | 292 | MODULE_LICENSE("GPL"); |
| 293 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>"); | 293 | MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>"); |
| 294 | MODULE_ALIAS_NFT_EXPR("nat"); | 294 | MODULE_ALIAS_NFT_EXPR("redir"); |
| @@ -31,6 +31,8 @@ static void nft_synproxy_tcp_options(struct synproxy_options *opts, · 30 unmodified lines | |||
| 31 | opts->options |= NF_SYNPROXY_OPT_ECN; | 31 | opts->options |= NF_SYNPROXY_OPT_ECN; |
| 32 | 32 | ||
| 33 | opts->options &= priv->info.options; | 33 | opts->options &= priv->info.options; |
| 34 | opts->mss_encode = opts->mss; | ||
| 35 | opts->mss = info->mss; | ||
| 34 | if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) | 36 | if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) |
| 35 | synproxy_init_timestamp_cookie(info, opts); | 37 | synproxy_init_timestamp_cookie(info, opts); |
| 36 | else | 38 | else |