Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf

Pablo Neira Ayuso says:

====================
Netfilter fixes for net

The following patchset contains Netfilter fixes for your net tree,
they are:

* Fix nf_trace in nftables if XT_TRACE=n, from Florian Westphal.

* Don't use the fast payload operation in nf_tables if the length is
not power of 2 or it is not aligned, from Nikolay Aleksandrov.

* Fix missing break statement the inet flavour of nft_reject, which
results in evaluating IPv4 packets with the IPv6 evaluation routine,
from Patrick McHardy.

* Fix wrong kconfig symbol in nft_meta to match the routing realm,
from Paul Bolle.

* Allocate the NAT null binding when creating new conntracks via
ctnetlink to avoid that several packets race at initializing the
the conntrack NAT extension, original patch from Florian Westphal,
revisited version from me.

* Fix DNAT handling in the snmp NAT helper, the same handling was being
done for SNAT and DNAT and 2.4 already contains that fix, from
Francois-Xavier Le Bail.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>

+61 -59
+4 -1
include/linux/skbuff.h
··· 2725 2725 2726 2726 static inline void nf_reset_trace(struct sk_buff *skb) 2727 2727 { 2728 - #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) 2728 + #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES) 2729 2729 skb->nf_trace = 0; 2730 2730 #endif 2731 2731 } ··· 2741 2741 #ifdef CONFIG_BRIDGE_NETFILTER 2742 2742 dst->nf_bridge = src->nf_bridge; 2743 2743 nf_bridge_get(src->nf_bridge); 2744 + #endif 2745 + #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) || defined(CONFIG_NF_TABLES) 2746 + dst->nf_trace = src->nf_trace; 2744 2747 #endif 2745 2748 } 2746 2749
-3
net/core/skbuff.c
··· 707 707 new->mark = old->mark; 708 708 new->skb_iif = old->skb_iif; 709 709 __nf_copy(new, old); 710 - #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) 711 - new->nf_trace = old->nf_trace; 712 - #endif 713 710 #ifdef CONFIG_NET_SCHED 714 711 new->tc_index = old->tc_index; 715 712 #ifdef CONFIG_NET_CLS_ACT
-3
net/ipv4/ip_output.c
··· 422 422 to->tc_index = from->tc_index; 423 423 #endif 424 424 nf_copy(to, from); 425 - #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) 426 - to->nf_trace = from->nf_trace; 427 - #endif 428 425 #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE) 429 426 to->ipvs_property = from->ipvs_property; 430 427 #endif
+2 -2
net/ipv4/netfilter/nf_nat_snmp_basic.c
··· 1198 1198 map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip); 1199 1199 } else { 1200 1200 /* DNAT replies */ 1201 - map.from = NOCT1(&ct->tuplehash[dir].tuple.src.u3.ip); 1202 - map.to = NOCT1(&ct->tuplehash[!dir].tuple.dst.u3.ip); 1201 + map.from = NOCT1(&ct->tuplehash[!dir].tuple.src.u3.ip); 1202 + map.to = NOCT1(&ct->tuplehash[dir].tuple.dst.u3.ip); 1203 1203 } 1204 1204 1205 1205 if (map.from == map.to)
-3
net/ipv6/ip6_output.c
··· 530 530 to->tc_index = from->tc_index; 531 531 #endif 532 532 nf_copy(to, from); 533 - #if IS_ENABLED(CONFIG_NETFILTER_XT_TARGET_TRACE) 534 - to->nf_trace = from->nf_trace; 535 - #endif 536 533 skb_copy_secmark(to, from); 537 534 } 538 535
+14 -21
net/netfilter/nf_conntrack_netlink.c
··· 1310 1310 } 1311 1311 1312 1312 static int 1313 - ctnetlink_change_nat(struct nf_conn *ct, const struct nlattr * const cda[]) 1313 + ctnetlink_setup_nat(struct nf_conn *ct, const struct nlattr * const cda[]) 1314 1314 { 1315 1315 #ifdef CONFIG_NF_NAT_NEEDED 1316 1316 int ret; 1317 1317 1318 - if (cda[CTA_NAT_DST]) { 1319 - ret = ctnetlink_parse_nat_setup(ct, 1320 - NF_NAT_MANIP_DST, 1321 - cda[CTA_NAT_DST]); 1322 - if (ret < 0) 1323 - return ret; 1324 - } 1325 - if (cda[CTA_NAT_SRC]) { 1326 - ret = ctnetlink_parse_nat_setup(ct, 1327 - NF_NAT_MANIP_SRC, 1328 - cda[CTA_NAT_SRC]); 1329 - if (ret < 0) 1330 - return ret; 1331 - } 1332 - return 0; 1318 + ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_DST, 1319 + cda[CTA_NAT_DST]); 1320 + if (ret < 0) 1321 + return ret; 1322 + 1323 + ret = ctnetlink_parse_nat_setup(ct, NF_NAT_MANIP_SRC, 1324 + cda[CTA_NAT_SRC]); 1325 + return ret; 1333 1326 #else 1327 + if (!cda[CTA_NAT_DST] && !cda[CTA_NAT_SRC]) 1328 + return 0; 1334 1329 return -EOPNOTSUPP; 1335 1330 #endif 1336 1331 } ··· 1654 1659 goto err2; 1655 1660 } 1656 1661 1657 - if (cda[CTA_NAT_SRC] || cda[CTA_NAT_DST]) { 1658 - err = ctnetlink_change_nat(ct, cda); 1659 - if (err < 0) 1660 - goto err2; 1661 - } 1662 + err = ctnetlink_setup_nat(ct, cda); 1663 + if (err < 0) 1664 + goto err2; 1662 1665 1663 1666 nf_ct_acct_ext_add(ct, GFP_ATOMIC); 1664 1667 nf_ct_tstamp_ext_add(ct, GFP_ATOMIC);
+35 -21
net/netfilter/nf_nat_core.c
··· 432 432 } 433 433 EXPORT_SYMBOL(nf_nat_setup_info); 434 434 435 - unsigned int 436 - nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) 435 + static unsigned int 436 + __nf_nat_alloc_null_binding(struct nf_conn *ct, enum nf_nat_manip_type manip) 437 437 { 438 438 /* Force range to this IP; let proto decide mapping for 439 439 * per-proto parts (hence not IP_NAT_RANGE_PROTO_SPECIFIED). 440 440 * Use reply in case it's already been mangled (eg local packet). 441 441 */ 442 442 union nf_inet_addr ip = 443 - (HOOK2MANIP(hooknum) == NF_NAT_MANIP_SRC ? 443 + (manip == NF_NAT_MANIP_SRC ? 444 444 ct->tuplehash[IP_CT_DIR_REPLY].tuple.dst.u3 : 445 445 ct->tuplehash[IP_CT_DIR_REPLY].tuple.src.u3); 446 446 struct nf_nat_range range = { ··· 448 448 .min_addr = ip, 449 449 .max_addr = ip, 450 450 }; 451 - return nf_nat_setup_info(ct, &range, HOOK2MANIP(hooknum)); 451 + return nf_nat_setup_info(ct, &range, manip); 452 + } 453 + 454 + unsigned int 455 + nf_nat_alloc_null_binding(struct nf_conn *ct, unsigned int hooknum) 456 + { 457 + return __nf_nat_alloc_null_binding(ct, HOOK2MANIP(hooknum)); 452 458 } 453 459 EXPORT_SYMBOL_GPL(nf_nat_alloc_null_binding); 454 460 ··· 708 702 709 703 static int 710 704 nfnetlink_parse_nat(const struct nlattr *nat, 711 - const struct nf_conn *ct, struct nf_nat_range *range) 705 + const struct nf_conn *ct, struct nf_nat_range *range, 706 + const struct nf_nat_l3proto *l3proto) 712 707 { 713 - const struct nf_nat_l3proto *l3proto; 714 708 struct nlattr *tb[CTA_NAT_MAX+1]; 715 709 int err; 716 710 ··· 720 714 if (err < 0) 721 715 return err; 722 716 723 - rcu_read_lock(); 724 - l3proto = __nf_nat_l3proto_find(nf_ct_l3num(ct)); 725 - if (l3proto == NULL) { 726 - err = -EAGAIN; 727 - goto out; 728 - } 729 717 err = l3proto->nlattr_to_range(tb, range); 730 718 if (err < 0) 731 - goto out; 719 + return err; 732 720 733 721 if (!tb[CTA_NAT_PROTO]) 734 - goto out; 722 + return 0; 735 723 736 - err = nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range); 737 - out: 738 - rcu_read_unlock(); 739 - return err; 724 + return nfnetlink_parse_nat_proto(tb[CTA_NAT_PROTO], ct, range); 740 725 } 741 726 727 + /* This function is called under rcu_read_lock() */ 742 728 static int 743 729 nfnetlink_parse_nat_setup(struct nf_conn *ct, 744 730 enum nf_nat_manip_type manip, 745 731 const struct nlattr *attr) 746 732 { 747 733 struct nf_nat_range range; 734 + const struct nf_nat_l3proto *l3proto; 748 735 int err; 749 736 750 - err = nfnetlink_parse_nat(attr, ct, &range); 737 + /* Should not happen, restricted to creating new conntracks 738 + * via ctnetlink. 739 + */ 740 + if (WARN_ON_ONCE(nf_nat_initialized(ct, manip))) 741 + return -EEXIST; 742 + 743 + /* Make sure that L3 NAT is there by when we call nf_nat_setup_info to 744 + * attach the null binding, otherwise this may oops. 745 + */ 746 + l3proto = __nf_nat_l3proto_find(nf_ct_l3num(ct)); 747 + if (l3proto == NULL) 748 + return -EAGAIN; 749 + 750 + /* No NAT information has been passed, allocate the null-binding */ 751 + if (attr == NULL) 752 + return __nf_nat_alloc_null_binding(ct, manip); 753 + 754 + err = nfnetlink_parse_nat(attr, ct, &range, l3proto); 751 755 if (err < 0) 752 756 return err; 753 - if (nf_nat_initialized(ct, manip)) 754 - return -EEXIST; 755 757 756 758 return nf_nat_setup_info(ct, &range, manip); 757 759 }
+2 -2
net/netfilter/nft_meta.c
··· 116 116 skb->sk->sk_socket->file->f_cred->fsgid); 117 117 read_unlock_bh(&skb->sk->sk_callback_lock); 118 118 break; 119 - #ifdef CONFIG_NET_CLS_ROUTE 119 + #ifdef CONFIG_IP_ROUTE_CLASSID 120 120 case NFT_META_RTCLASSID: { 121 121 const struct dst_entry *dst = skb_dst(skb); 122 122 ··· 199 199 case NFT_META_OIFTYPE: 200 200 case NFT_META_SKUID: 201 201 case NFT_META_SKGID: 202 - #ifdef CONFIG_NET_CLS_ROUTE 202 + #ifdef CONFIG_IP_ROUTE_CLASSID 203 203 case NFT_META_RTCLASSID: 204 204 #endif 205 205 #ifdef CONFIG_NETWORK_SECMARK
+2 -1
net/netfilter/nft_payload.c
··· 135 135 if (len == 0 || len > FIELD_SIZEOF(struct nft_data, data)) 136 136 return ERR_PTR(-EINVAL); 137 137 138 - if (len <= 4 && IS_ALIGNED(offset, len) && base != NFT_PAYLOAD_LL_HEADER) 138 + if (len <= 4 && is_power_of_2(len) && IS_ALIGNED(offset, len) && 139 + base != NFT_PAYLOAD_LL_HEADER) 139 140 return &nft_payload_fast_ops; 140 141 else 141 142 return &nft_payload_ops;
+2 -2
net/netfilter/nft_reject_inet.c
··· 21 21 { 22 22 switch (pkt->ops->pf) { 23 23 case NFPROTO_IPV4: 24 - nft_reject_ipv4_eval(expr, data, pkt); 24 + return nft_reject_ipv4_eval(expr, data, pkt); 25 25 case NFPROTO_IPV6: 26 - nft_reject_ipv6_eval(expr, data, pkt); 26 + return nft_reject_ipv6_eval(expr, data, pkt); 27 27 } 28 28 } 29 29