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

Configure Feed

Select the types of activity you want to include in your feed.

Merge git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next

Pablo Neira Ayuso says:

====================
Netfilter updates for net-next

The following patches contains Netfilter updates for net-next:

1) .br_defrag indirection depends on CONFIG_NF_DEFRAG_IPV6, from wenxu.

2) Remove unnecessary memset() in ipset, from Florent Fourcot.

3) Merge control plane addition and deletion in ipset, also from Florent.

4) A few missing check for nla_parse() in ipset, from Aditya Pakki
and Jozsef Kadlecsik.

5) Incorrect cleanup in error path of xt_set version 3, from Jozsef.

6) Memory accounting problems when resizing in ipset, from Stefano Brivio.

7) Jozsef updates his email to @netfilter.org, this batch comes with a
conflict resolution with recent SPDX header updates.

8) Add to create custom conntrack expectations via nftables, from
Stephane Veyret.

9) A lookup optimization for conntrack, from Florian Westphal.

10) Check for supported flags in xt_owner.

11) Support for pernet sysctl in br_netfilter, patches
from Christian Brauner.

12) Patches to move common synproxy infrastructure to nf_synproxy.c,
to prepare the synproxy support for nf_tables, patches from
Fernando Fernandez Mancera.

13) Support to restore expiration time in set element, from Laura Garcia.

14) Fix recent rewrite of netfilter IPv6 to avoid indirections
when CONFIG_IPV6 is unset, from Arnd Bergmann.

15) Always reset vlan tag on skbuff fraglist when refragmenting in
bridge conntrack, from wenxu.

16) Support to match IPv4 options in nf_tables, from Stephen Suryaputra.
====================

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

+1611 -1127
+1 -1
CREDITS
··· 1800 1800 S: Denmark 1801 1801 1802 1802 N: Jozsef Kadlecsik 1803 - E: kadlec@blackhole.kfki.hu 1803 + E: kadlec@netfilter.org 1804 1804 P: 1024D/470DB964 4CB3 1A05 713E 9BF7 FAC5 5809 DD8C B7B1 470D B964 1805 1805 D: netfilter: TCP window tracking code 1806 1806 D: netfilter: raw table
+1 -1
MAINTAINERS
··· 10866 10866 10867 10867 NETFILTER 10868 10868 M: Pablo Neira Ayuso <pablo@netfilter.org> 10869 - M: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 10869 + M: Jozsef Kadlecsik <kadlec@netfilter.org> 10870 10870 M: Florian Westphal <fw@strlen.de> 10871 10871 L: netfilter-devel@vger.kernel.org 10872 10872 L: coreteam@netfilter.org
+1 -1
include/linux/jhash.h
··· 17 17 * if SELF_TEST is defined. You can use this free for any purpose. It's in 18 18 * the public domain. It has no warranty. 19 19 * 20 - * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@blackhole.kfki.hu) 20 + * Copyright (C) 2009-2010 Jozsef Kadlecsik (kadlec@netfilter.org) 21 21 * 22 22 * I've modified Bob's hash to be useful in the Linux kernel, and 23 23 * any bugs present are my fault.
+1 -1
include/linux/netfilter/ipset/ip_set.h
··· 2 2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 3 3 * Patrick Schaaf <bof@bof.de> 4 4 * Martin Josefsson <gandalf@wlug.westbo.se> 5 - * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 + * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> 6 6 */ 7 7 #ifndef _IP_SET_H 8 8 #define _IP_SET_H
+1 -2
include/linux/netfilter/ipset/ip_set_counter.h
··· 2 2 #ifndef _IP_SET_COUNTER_H 3 3 #define _IP_SET_COUNTER_H 4 4 5 - /* Copyright (C) 2015 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 6 - */ 5 + /* Copyright (C) 2015 Jozsef Kadlecsik <kadlec@netfilter.org> */ 7 6 8 7 #ifdef __KERNEL__ 9 8
+1 -2
include/linux/netfilter/ipset/ip_set_skbinfo.h
··· 2 2 #ifndef _IP_SET_SKBINFO_H 3 3 #define _IP_SET_SKBINFO_H 4 4 5 - /* Copyright (C) 2015 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 6 - */ 5 + /* Copyright (C) 2015 Jozsef Kadlecsik <kadlec@netfilter.org> */ 7 6 8 7 #ifdef __KERNEL__ 9 8
+1 -2
include/linux/netfilter/ipset/ip_set_timeout.h
··· 2 2 #ifndef _IP_SET_TIMEOUT_H 3 3 #define _IP_SET_TIMEOUT_H 4 4 5 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 6 - */ 5 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 7 6 8 7 #ifdef __KERNEL__ 9 8
+50 -4
include/linux/netfilter_ipv6.h
··· 8 8 #define __LINUX_IP6_NETFILTER_H 9 9 10 10 #include <uapi/linux/netfilter_ipv6.h> 11 + #include <net/tcp.h> 11 12 12 13 /* Extra routing may needed on local out, as the QUEUE target never returns 13 14 * control to the table. ··· 36 35 struct in6_addr *saddr); 37 36 int (*route)(struct net *net, struct dst_entry **dst, struct flowi *fl, 38 37 bool strict); 38 + u32 (*cookie_init_sequence)(const struct ipv6hdr *iph, 39 + const struct tcphdr *th, u16 *mssp); 40 + int (*cookie_v6_check)(const struct ipv6hdr *iph, 41 + const struct tcphdr *th, __u32 cookie); 39 42 #endif 40 43 void (*route_input)(struct sk_buff *skb); 41 44 int (*fragment)(struct net *net, struct sock *sk, struct sk_buff *skb, ··· 75 70 return 1; 76 71 77 72 return v6_ops->chk_addr(net, addr, dev, strict); 78 - #else 73 + #elif IS_BUILTIN(CONFIG_IPV6) 79 74 return ipv6_chk_addr(net, addr, dev, strict); 75 + #else 76 + return 1; 80 77 #endif 81 78 } 82 79 ··· 115 108 return 1; 116 109 117 110 return v6_ops->br_defrag(net, skb, user); 118 - #else 111 + #elif IS_BUILTIN(CONFIG_IPV6) 119 112 return nf_ct_frag6_gather(net, skb, user); 113 + #else 114 + return 1; 120 115 #endif 121 116 } 122 117 ··· 142 133 return 1; 143 134 144 135 return v6_ops->br_fragment(net, sk, skb, data, output); 145 - #else 136 + #elif IS_BUILTIN(CONFIG_IPV6) 146 137 return br_ip6_fragment(net, sk, skb, data, output); 138 + #else 139 + return 1; 147 140 #endif 148 141 } 149 142 ··· 160 149 return -EHOSTUNREACH; 161 150 162 151 return v6_ops->route_me_harder(net, skb); 163 - #else 152 + #elif IS_BUILTIN(CONFIG_IPV6) 164 153 return ip6_route_me_harder(net, skb); 154 + #else 155 + return -EHOSTUNREACH; 165 156 #endif 157 + } 158 + 159 + static inline u32 nf_ipv6_cookie_init_sequence(const struct ipv6hdr *iph, 160 + const struct tcphdr *th, 161 + u16 *mssp) 162 + { 163 + #if IS_ENABLED(CONFIG_SYN_COOKIES) 164 + #if IS_MODULE(CONFIG_IPV6) 165 + const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops(); 166 + 167 + if (v6_ops) 168 + return v6_ops->cookie_init_sequence(iph, th, mssp); 169 + #elif IS_BUILTIN(CONFIG_IPV6) 170 + return __cookie_v6_init_sequence(iph, th, mssp); 171 + #endif 172 + #endif 173 + return 0; 174 + } 175 + 176 + static inline int nf_cookie_v6_check(const struct ipv6hdr *iph, 177 + const struct tcphdr *th, __u32 cookie) 178 + { 179 + #if IS_ENABLED(CONFIG_SYN_COOKIES) 180 + #if IS_MODULE(CONFIG_IPV6) 181 + const struct nf_ipv6_ops *v6_ops = nf_get_ipv6_ops(); 182 + 183 + if (v6_ops) 184 + return v6_ops->cookie_v6_check(iph, th, cookie); 185 + #elif IS_BUILTIN(CONFIG_IPV6) 186 + return __cookie_v6_check(iph, th, cookie); 187 + #endif 188 + #endif 189 + return 0; 166 190 } 167 191 168 192 __sum16 nf_ip6_checksum(struct sk_buff *skb, unsigned int hook,
+2 -1
include/net/netfilter/br_netfilter.h
··· 42 42 return port ? &port->br->fake_rtable : NULL; 43 43 } 44 44 45 - struct net_device *setup_pre_routing(struct sk_buff *skb); 45 + struct net_device *setup_pre_routing(struct sk_buff *skb, 46 + const struct net *net); 46 47 47 48 #if IS_ENABLED(CONFIG_IPV6) 48 49 int br_validate_ipv6(struct net *net, struct sk_buff *skb);
+3 -4
include/net/netfilter/nf_conntrack.h
··· 70 70 struct nf_conntrack ct_general; 71 71 72 72 spinlock_t lock; 73 - u16 cpu; 73 + /* jiffies32 when this ct is considered dead */ 74 + u32 timeout; 74 75 75 76 #ifdef CONFIG_NF_CONNTRACK_ZONES 76 77 struct nf_conntrack_zone zone; ··· 83 82 /* Have we seen traffic both ways yet? (bitset) */ 84 83 unsigned long status; 85 84 86 - /* jiffies32 when this ct is considered dead */ 87 - u32 timeout; 88 - 85 + u16 cpu; 89 86 possible_net_t ct_net; 90 87 91 88 #if IS_ENABLED(CONFIG_NF_NAT)
+2 -11
include/net/netfilter/nf_conntrack_synproxy.h
··· 72 72 }; 73 73 74 74 struct tcphdr; 75 - struct xt_synproxy_info; 75 + struct nf_synproxy_info; 76 76 bool synproxy_parse_options(const struct sk_buff *skb, unsigned int doff, 77 77 const struct tcphdr *th, 78 78 struct synproxy_options *opts); 79 - unsigned int synproxy_options_size(const struct synproxy_options *opts); 80 - void synproxy_build_options(struct tcphdr *th, 81 - const struct synproxy_options *opts); 82 79 83 - void synproxy_init_timestamp_cookie(const struct xt_synproxy_info *info, 80 + void synproxy_init_timestamp_cookie(const struct nf_synproxy_info *info, 84 81 struct synproxy_options *opts); 85 - void synproxy_check_timestamp_cookie(struct synproxy_options *opts); 86 - 87 - unsigned int synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff, 88 - struct tcphdr *th, struct nf_conn *ct, 89 - enum ip_conntrack_info ctinfo, 90 - const struct nf_conn_synproxy *synproxy); 91 82 92 83 #endif /* _NF_CONNTRACK_SYNPROXY_H */
+44
include/net/netfilter/nf_synproxy.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _NF_SYNPROXY_SHARED_H 3 + #define _NF_SYNPROXY_SHARED_H 4 + 5 + #include <linux/module.h> 6 + #include <linux/skbuff.h> 7 + #include <net/ip6_checksum.h> 8 + #include <net/ip6_route.h> 9 + #include <net/tcp.h> 10 + 11 + #include <net/netfilter/nf_conntrack_seqadj.h> 12 + #include <net/netfilter/nf_conntrack_synproxy.h> 13 + 14 + void synproxy_send_client_synack(struct net *net, const struct sk_buff *skb, 15 + const struct tcphdr *th, 16 + const struct synproxy_options *opts); 17 + 18 + bool synproxy_recv_client_ack(struct net *net, 19 + const struct sk_buff *skb, 20 + const struct tcphdr *th, 21 + struct synproxy_options *opts, u32 recv_seq); 22 + 23 + unsigned int ipv4_synproxy_hook(void *priv, struct sk_buff *skb, 24 + const struct nf_hook_state *nhs); 25 + int nf_synproxy_ipv4_init(struct synproxy_net *snet, struct net *net); 26 + void nf_synproxy_ipv4_fini(struct synproxy_net *snet, struct net *net); 27 + 28 + #if IS_ENABLED(CONFIG_IPV6) 29 + void synproxy_send_client_synack_ipv6(struct net *net, 30 + const struct sk_buff *skb, 31 + const struct tcphdr *th, 32 + const struct synproxy_options *opts); 33 + 34 + bool synproxy_recv_client_ack_ipv6(struct net *net, const struct sk_buff *skb, 35 + const struct tcphdr *th, 36 + struct synproxy_options *opts, u32 recv_seq); 37 + 38 + unsigned int ipv6_synproxy_hook(void *priv, struct sk_buff *skb, 39 + const struct nf_hook_state *nhs); 40 + int nf_synproxy_ipv6_init(struct synproxy_net *snet, struct net *net); 41 + void nf_synproxy_ipv6_fini(struct synproxy_net *snet, struct net *net); 42 + #endif /* CONFIG_IPV6 */ 43 + 44 + #endif /* _NF_SYNPROXY_SHARED_H */
+1 -1
include/net/netfilter/nf_tables.h
··· 636 636 void *nft_set_elem_init(const struct nft_set *set, 637 637 const struct nft_set_ext_tmpl *tmpl, 638 638 const u32 *key, const u32 *data, 639 - u64 timeout, gfp_t gfp); 639 + u64 timeout, u64 expiration, gfp_t gfp); 640 640 void nft_set_elem_destroy(const struct nft_set *set, void *elem, 641 641 bool destroy_expr); 642 642
+1 -1
include/uapi/linux/netfilter/ipset/ip_set.h
··· 2 2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 3 3 * Patrick Schaaf <bof@bof.de> 4 4 * Martin Josefsson <gandalf@wlug.westbo.se> 5 - * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 + * Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@netfilter.org> 6 6 * 7 7 * This program is free software; you can redistribute it and/or modify 8 8 * it under the terms of the GNU General Public License version 2 as
+19
include/uapi/linux/netfilter/nf_SYNPROXY.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + #ifndef _NF_SYNPROXY_H 3 + #define _NF_SYNPROXY_H 4 + 5 + #include <linux/types.h> 6 + 7 + #define NF_SYNPROXY_OPT_MSS 0x01 8 + #define NF_SYNPROXY_OPT_WSCALE 0x02 9 + #define NF_SYNPROXY_OPT_SACK_PERM 0x04 10 + #define NF_SYNPROXY_OPT_TIMESTAMP 0x08 11 + #define NF_SYNPROXY_OPT_ECN 0x10 12 + 13 + struct nf_synproxy_info { 14 + __u8 options; 15 + __u8 wscale; 16 + __u16 mss; 17 + }; 18 + 19 + #endif /* _NF_SYNPROXY_H */
+15 -1
include/uapi/linux/netfilter/nf_tables.h
··· 730 730 * 731 731 * @NFT_EXTHDR_OP_IPV6: match against ipv6 extension headers 732 732 * @NFT_EXTHDR_OP_TCP: match against tcp options 733 + * @NFT_EXTHDR_OP_IPV4: match against ipv4 options 733 734 */ 734 735 enum nft_exthdr_op { 735 736 NFT_EXTHDR_OP_IPV6, 736 737 NFT_EXTHDR_OP_TCPOPT, 738 + NFT_EXTHDR_OP_IPV4, 737 739 __NFT_EXTHDR_OP_MAX 738 740 }; 739 741 #define NFT_EXTHDR_OP_MAX (__NFT_EXTHDR_OP_MAX - 1) ··· 1447 1445 }; 1448 1446 #define NFTA_CT_TIMEOUT_MAX (__NFTA_CT_TIMEOUT_MAX - 1) 1449 1447 1448 + enum nft_ct_expectation_attributes { 1449 + NFTA_CT_EXPECT_UNSPEC, 1450 + NFTA_CT_EXPECT_L3PROTO, 1451 + NFTA_CT_EXPECT_L4PROTO, 1452 + NFTA_CT_EXPECT_DPORT, 1453 + NFTA_CT_EXPECT_TIMEOUT, 1454 + NFTA_CT_EXPECT_SIZE, 1455 + __NFTA_CT_EXPECT_MAX, 1456 + }; 1457 + #define NFTA_CT_EXPECT_MAX (__NFTA_CT_EXPECT_MAX - 1) 1458 + 1450 1459 #define NFT_OBJECT_UNSPEC 0 1451 1460 #define NFT_OBJECT_COUNTER 1 1452 1461 #define NFT_OBJECT_QUOTA 2 ··· 1467 1454 #define NFT_OBJECT_TUNNEL 6 1468 1455 #define NFT_OBJECT_CT_TIMEOUT 7 1469 1456 #define NFT_OBJECT_SECMARK 8 1470 - #define __NFT_OBJECT_MAX 9 1457 + #define NFT_OBJECT_CT_EXPECT 9 1458 + #define __NFT_OBJECT_MAX 10 1471 1459 #define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1) 1472 1460 1473 1461 /**
+7 -11
include/uapi/linux/netfilter/xt_SYNPROXY.h
··· 2 2 #ifndef _XT_SYNPROXY_H 3 3 #define _XT_SYNPROXY_H 4 4 5 - #include <linux/types.h> 5 + #include <linux/netfilter/nf_SYNPROXY.h> 6 6 7 - #define XT_SYNPROXY_OPT_MSS 0x01 8 - #define XT_SYNPROXY_OPT_WSCALE 0x02 9 - #define XT_SYNPROXY_OPT_SACK_PERM 0x04 10 - #define XT_SYNPROXY_OPT_TIMESTAMP 0x08 11 - #define XT_SYNPROXY_OPT_ECN 0x10 7 + #define XT_SYNPROXY_OPT_MSS NF_SYNPROXY_OPT_MSS 8 + #define XT_SYNPROXY_OPT_WSCALE NF_SYNPROXY_OPT_WSCALE 9 + #define XT_SYNPROXY_OPT_SACK_PERM NF_SYNPROXY_OPT_SACK_PERM 10 + #define XT_SYNPROXY_OPT_TIMESTAMP NF_SYNPROXY_OPT_TIMESTAMP 11 + #define XT_SYNPROXY_OPT_ECN NF_SYNPROXY_OPT_ECN 12 12 13 - struct xt_synproxy_info { 14 - __u8 options; 15 - __u8 wscale; 16 - __u16 mss; 17 - }; 13 + #define xt_synproxy_info nf_synproxy_info 18 14 19 15 #endif /* _XT_SYNPROXY_H */
+5
include/uapi/linux/netfilter/xt_owner.h
··· 11 11 XT_OWNER_SUPPL_GROUPS = 1 << 3, 12 12 }; 13 13 14 + #define XT_OWNER_MASK (XT_OWNER_UID | \ 15 + XT_OWNER_GID | \ 16 + XT_OWNER_SOCKET | \ 17 + XT_OWNER_SUPPL_GROUPS) 18 + 14 19 struct xt_owner_match_info { 15 20 __u32 uid_min, uid_max; 16 21 __u32 gid_min, gid_max;
+161 -86
net/bridge/br_netfilter_hooks.c
··· 47 47 48 48 struct brnf_net { 49 49 bool enabled; 50 - }; 51 50 52 51 #ifdef CONFIG_SYSCTL 53 - static struct ctl_table_header *brnf_sysctl_header; 54 - static int brnf_call_iptables __read_mostly = 1; 55 - static int brnf_call_ip6tables __read_mostly = 1; 56 - static int brnf_call_arptables __read_mostly = 1; 57 - static int brnf_filter_vlan_tagged __read_mostly; 58 - static int brnf_filter_pppoe_tagged __read_mostly; 59 - static int brnf_pass_vlan_indev __read_mostly; 60 - #else 61 - #define brnf_call_iptables 1 62 - #define brnf_call_ip6tables 1 63 - #define brnf_call_arptables 1 64 - #define brnf_filter_vlan_tagged 0 65 - #define brnf_filter_pppoe_tagged 0 66 - #define brnf_pass_vlan_indev 0 52 + struct ctl_table_header *ctl_hdr; 67 53 #endif 54 + 55 + /* default value is 1 */ 56 + int call_iptables; 57 + int call_ip6tables; 58 + int call_arptables; 59 + 60 + /* default value is 0 */ 61 + int filter_vlan_tagged; 62 + int filter_pppoe_tagged; 63 + int pass_vlan_indev; 64 + }; 68 65 69 66 #define IS_IP(skb) \ 70 67 (!skb_vlan_tag_present(skb) && skb->protocol == htons(ETH_P_IP)) ··· 82 85 return 0; 83 86 } 84 87 85 - #define IS_VLAN_IP(skb) \ 86 - (vlan_proto(skb) == htons(ETH_P_IP) && \ 87 - brnf_filter_vlan_tagged) 88 + static inline bool is_vlan_ip(const struct sk_buff *skb, const struct net *net) 89 + { 90 + struct brnf_net *brnet = net_generic(net, brnf_net_id); 88 91 89 - #define IS_VLAN_IPV6(skb) \ 90 - (vlan_proto(skb) == htons(ETH_P_IPV6) && \ 91 - brnf_filter_vlan_tagged) 92 + return vlan_proto(skb) == htons(ETH_P_IP) && brnet->filter_vlan_tagged; 93 + } 92 94 93 - #define IS_VLAN_ARP(skb) \ 94 - (vlan_proto(skb) == htons(ETH_P_ARP) && \ 95 - brnf_filter_vlan_tagged) 95 + static inline bool is_vlan_ipv6(const struct sk_buff *skb, 96 + const struct net *net) 97 + { 98 + struct brnf_net *brnet = net_generic(net, brnf_net_id); 99 + 100 + return vlan_proto(skb) == htons(ETH_P_IPV6) && 101 + brnet->filter_vlan_tagged; 102 + } 103 + 104 + static inline bool is_vlan_arp(const struct sk_buff *skb, const struct net *net) 105 + { 106 + struct brnf_net *brnet = net_generic(net, brnf_net_id); 107 + 108 + return vlan_proto(skb) == htons(ETH_P_ARP) && brnet->filter_vlan_tagged; 109 + } 96 110 97 111 static inline __be16 pppoe_proto(const struct sk_buff *skb) 98 112 { ··· 111 103 sizeof(struct pppoe_hdr))); 112 104 } 113 105 114 - #define IS_PPPOE_IP(skb) \ 115 - (skb->protocol == htons(ETH_P_PPP_SES) && \ 116 - pppoe_proto(skb) == htons(PPP_IP) && \ 117 - brnf_filter_pppoe_tagged) 106 + static inline bool is_pppoe_ip(const struct sk_buff *skb, const struct net *net) 107 + { 108 + struct brnf_net *brnet = net_generic(net, brnf_net_id); 118 109 119 - #define IS_PPPOE_IPV6(skb) \ 120 - (skb->protocol == htons(ETH_P_PPP_SES) && \ 121 - pppoe_proto(skb) == htons(PPP_IPV6) && \ 122 - brnf_filter_pppoe_tagged) 110 + return skb->protocol == htons(ETH_P_PPP_SES) && 111 + pppoe_proto(skb) == htons(PPP_IP) && brnet->filter_pppoe_tagged; 112 + } 113 + 114 + static inline bool is_pppoe_ipv6(const struct sk_buff *skb, 115 + const struct net *net) 116 + { 117 + struct brnf_net *brnet = net_generic(net, brnf_net_id); 118 + 119 + return skb->protocol == htons(ETH_P_PPP_SES) && 120 + pppoe_proto(skb) == htons(PPP_IPV6) && 121 + brnet->filter_pppoe_tagged; 122 + } 123 123 124 124 /* largest possible L2 header, see br_nf_dev_queue_xmit() */ 125 125 #define NF_BRIDGE_MAX_MAC_HEADER_LENGTH (PPPOE_SES_HLEN + ETH_HLEN) ··· 424 408 return 0; 425 409 } 426 410 427 - static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, const struct net_device *dev) 411 + static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, 412 + const struct net_device *dev, 413 + const struct net *net) 428 414 { 429 415 struct net_device *vlan, *br; 416 + struct brnf_net *brnet = net_generic(net, brnf_net_id); 430 417 431 418 br = bridge_parent(dev); 432 - if (brnf_pass_vlan_indev == 0 || !skb_vlan_tag_present(skb)) 419 + 420 + if (brnet->pass_vlan_indev == 0 || !skb_vlan_tag_present(skb)) 433 421 return br; 434 422 435 423 vlan = __vlan_find_dev_deep_rcu(br, skb->vlan_proto, ··· 443 423 } 444 424 445 425 /* Some common code for IPv4/IPv6 */ 446 - struct net_device *setup_pre_routing(struct sk_buff *skb) 426 + struct net_device *setup_pre_routing(struct sk_buff *skb, const struct net *net) 447 427 { 448 428 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); 449 429 ··· 454 434 455 435 nf_bridge->in_prerouting = 1; 456 436 nf_bridge->physindev = skb->dev; 457 - skb->dev = brnf_get_logical_dev(skb, skb->dev); 437 + skb->dev = brnf_get_logical_dev(skb, skb->dev, net); 458 438 459 439 if (skb->protocol == htons(ETH_P_8021Q)) 460 440 nf_bridge->orig_proto = BRNF_PROTO_8021Q; ··· 480 460 struct net_bridge_port *p; 481 461 struct net_bridge *br; 482 462 __u32 len = nf_bridge_encap_header_len(skb); 463 + struct brnf_net *brnet; 483 464 484 465 if (unlikely(!pskb_may_pull(skb, len))) 485 466 return NF_DROP; ··· 490 469 return NF_DROP; 491 470 br = p->br; 492 471 493 - if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) { 494 - if (!brnf_call_ip6tables && 472 + brnet = net_generic(state->net, brnf_net_id); 473 + if (IS_IPV6(skb) || is_vlan_ipv6(skb, state->net) || 474 + is_pppoe_ipv6(skb, state->net)) { 475 + if (!brnet->call_ip6tables && 495 476 !br_opt_get(br, BROPT_NF_CALL_IP6TABLES)) 496 477 return NF_ACCEPT; 497 478 ··· 501 478 return br_nf_pre_routing_ipv6(priv, skb, state); 502 479 } 503 480 504 - if (!brnf_call_iptables && !br_opt_get(br, BROPT_NF_CALL_IPTABLES)) 481 + if (!brnet->call_iptables && !br_opt_get(br, BROPT_NF_CALL_IPTABLES)) 505 482 return NF_ACCEPT; 506 483 507 - if (!IS_IP(skb) && !IS_VLAN_IP(skb) && !IS_PPPOE_IP(skb)) 484 + if (!IS_IP(skb) && !is_vlan_ip(skb, state->net) && 485 + !is_pppoe_ip(skb, state->net)) 508 486 return NF_ACCEPT; 509 487 510 488 nf_bridge_pull_encap_header_rcsum(skb); ··· 515 491 516 492 if (!nf_bridge_alloc(skb)) 517 493 return NF_DROP; 518 - if (!setup_pre_routing(skb)) 494 + if (!setup_pre_routing(skb, state->net)) 519 495 return NF_DROP; 520 496 521 497 nf_bridge = nf_bridge_info_get(skb); ··· 538 514 struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb); 539 515 struct net_device *in; 540 516 541 - if (!IS_ARP(skb) && !IS_VLAN_ARP(skb)) { 517 + if (!IS_ARP(skb) && !is_vlan_arp(skb, net)) { 542 518 543 519 if (skb->protocol == htons(ETH_P_IP)) 544 520 nf_bridge->frag_max_size = IPCB(skb)->frag_max_size; ··· 593 569 if (!parent) 594 570 return NF_DROP; 595 571 596 - if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) 572 + if (IS_IP(skb) || is_vlan_ip(skb, state->net) || 573 + is_pppoe_ip(skb, state->net)) 597 574 pf = NFPROTO_IPV4; 598 - else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) 575 + else if (IS_IPV6(skb) || is_vlan_ipv6(skb, state->net) || 576 + is_pppoe_ipv6(skb, state->net)) 599 577 pf = NFPROTO_IPV6; 600 578 else 601 579 return NF_ACCEPT; ··· 628 602 skb->protocol = htons(ETH_P_IPV6); 629 603 630 604 NF_HOOK(pf, NF_INET_FORWARD, state->net, NULL, skb, 631 - brnf_get_logical_dev(skb, state->in), 605 + brnf_get_logical_dev(skb, state->in, state->net), 632 606 parent, br_nf_forward_finish); 633 607 634 608 return NF_STOLEN; ··· 641 615 struct net_bridge_port *p; 642 616 struct net_bridge *br; 643 617 struct net_device **d = (struct net_device **)(skb->cb); 618 + struct brnf_net *brnet; 644 619 645 620 p = br_port_get_rcu(state->out); 646 621 if (p == NULL) 647 622 return NF_ACCEPT; 648 623 br = p->br; 649 624 650 - if (!brnf_call_arptables && !br_opt_get(br, BROPT_NF_CALL_ARPTABLES)) 625 + brnet = net_generic(state->net, brnf_net_id); 626 + if (!brnet->call_arptables && !br_opt_get(br, BROPT_NF_CALL_ARPTABLES)) 651 627 return NF_ACCEPT; 652 628 653 629 if (!IS_ARP(skb)) { 654 - if (!IS_VLAN_ARP(skb)) 630 + if (!is_vlan_arp(skb, state->net)) 655 631 return NF_ACCEPT; 656 632 nf_bridge_pull_encap_header(skb); 657 633 } 658 634 659 635 if (arp_hdr(skb)->ar_pln != 4) { 660 - if (IS_VLAN_ARP(skb)) 636 + if (is_vlan_arp(skb, state->net)) 661 637 nf_bridge_push_encap_header(skb); 662 638 return NF_ACCEPT; 663 639 } ··· 819 791 if (!realoutdev) 820 792 return NF_DROP; 821 793 822 - if (IS_IP(skb) || IS_VLAN_IP(skb) || IS_PPPOE_IP(skb)) 794 + if (IS_IP(skb) || is_vlan_ip(skb, state->net) || 795 + is_pppoe_ip(skb, state->net)) 823 796 pf = NFPROTO_IPV4; 824 - else if (IS_IPV6(skb) || IS_VLAN_IPV6(skb) || IS_PPPOE_IPV6(skb)) 797 + else if (IS_IPV6(skb) || is_vlan_ipv6(skb, state->net) || 798 + is_pppoe_ipv6(skb, state->net)) 825 799 pf = NFPROTO_IPV6; 826 800 else 827 801 return NF_ACCEPT; ··· 976 946 return NOTIFY_OK; 977 947 } 978 948 979 - static void __net_exit brnf_exit_net(struct net *net) 980 - { 981 - struct brnf_net *brnet = net_generic(net, brnf_net_id); 982 - 983 - if (!brnet->enabled) 984 - return; 985 - 986 - nf_unregister_net_hooks(net, br_nf_ops, ARRAY_SIZE(br_nf_ops)); 987 - brnet->enabled = false; 988 - } 989 - 990 - static struct pernet_operations brnf_net_ops __read_mostly = { 991 - .exit = brnf_exit_net, 992 - .id = &brnf_net_id, 993 - .size = sizeof(struct brnf_net), 994 - }; 995 - 996 949 static struct notifier_block brnf_notifier __read_mostly = { 997 950 .notifier_call = brnf_device_event, 998 951 }; ··· 1034 1021 static struct ctl_table brnf_table[] = { 1035 1022 { 1036 1023 .procname = "bridge-nf-call-arptables", 1037 - .data = &brnf_call_arptables, 1038 1024 .maxlen = sizeof(int), 1039 1025 .mode = 0644, 1040 1026 .proc_handler = brnf_sysctl_call_tables, 1041 1027 }, 1042 1028 { 1043 1029 .procname = "bridge-nf-call-iptables", 1044 - .data = &brnf_call_iptables, 1045 1030 .maxlen = sizeof(int), 1046 1031 .mode = 0644, 1047 1032 .proc_handler = brnf_sysctl_call_tables, 1048 1033 }, 1049 1034 { 1050 1035 .procname = "bridge-nf-call-ip6tables", 1051 - .data = &brnf_call_ip6tables, 1052 1036 .maxlen = sizeof(int), 1053 1037 .mode = 0644, 1054 1038 .proc_handler = brnf_sysctl_call_tables, 1055 1039 }, 1056 1040 { 1057 1041 .procname = "bridge-nf-filter-vlan-tagged", 1058 - .data = &brnf_filter_vlan_tagged, 1059 1042 .maxlen = sizeof(int), 1060 1043 .mode = 0644, 1061 1044 .proc_handler = brnf_sysctl_call_tables, 1062 1045 }, 1063 1046 { 1064 1047 .procname = "bridge-nf-filter-pppoe-tagged", 1065 - .data = &brnf_filter_pppoe_tagged, 1066 1048 .maxlen = sizeof(int), 1067 1049 .mode = 0644, 1068 1050 .proc_handler = brnf_sysctl_call_tables, 1069 1051 }, 1070 1052 { 1071 1053 .procname = "bridge-nf-pass-vlan-input-dev", 1072 - .data = &brnf_pass_vlan_indev, 1073 1054 .maxlen = sizeof(int), 1074 1055 .mode = 0644, 1075 1056 .proc_handler = brnf_sysctl_call_tables, 1076 1057 }, 1077 1058 { } 1078 1059 }; 1060 + 1061 + static inline void br_netfilter_sysctl_default(struct brnf_net *brnf) 1062 + { 1063 + brnf->call_iptables = 1; 1064 + brnf->call_ip6tables = 1; 1065 + brnf->call_arptables = 1; 1066 + brnf->filter_vlan_tagged = 0; 1067 + brnf->filter_pppoe_tagged = 0; 1068 + brnf->pass_vlan_indev = 0; 1069 + } 1070 + 1071 + static int br_netfilter_sysctl_init_net(struct net *net) 1072 + { 1073 + struct ctl_table *table = brnf_table; 1074 + struct brnf_net *brnet; 1075 + 1076 + if (!net_eq(net, &init_net)) { 1077 + table = kmemdup(table, sizeof(brnf_table), GFP_KERNEL); 1078 + if (!table) 1079 + return -ENOMEM; 1080 + } 1081 + 1082 + brnet = net_generic(net, brnf_net_id); 1083 + table[0].data = &brnet->call_arptables; 1084 + table[1].data = &brnet->call_iptables; 1085 + table[2].data = &brnet->call_ip6tables; 1086 + table[3].data = &brnet->filter_vlan_tagged; 1087 + table[4].data = &brnet->filter_pppoe_tagged; 1088 + table[5].data = &brnet->pass_vlan_indev; 1089 + 1090 + br_netfilter_sysctl_default(brnet); 1091 + 1092 + brnet->ctl_hdr = register_net_sysctl(net, "net/bridge", table); 1093 + if (!brnet->ctl_hdr) { 1094 + if (!net_eq(net, &init_net)) 1095 + kfree(table); 1096 + 1097 + return -ENOMEM; 1098 + } 1099 + 1100 + return 0; 1101 + } 1102 + 1103 + static void br_netfilter_sysctl_exit_net(struct net *net, 1104 + struct brnf_net *brnet) 1105 + { 1106 + struct ctl_table *table = brnet->ctl_hdr->ctl_table_arg; 1107 + 1108 + unregister_net_sysctl_table(brnet->ctl_hdr); 1109 + if (!net_eq(net, &init_net)) 1110 + kfree(table); 1111 + } 1112 + 1113 + static int __net_init brnf_init_net(struct net *net) 1114 + { 1115 + return br_netfilter_sysctl_init_net(net); 1116 + } 1079 1117 #endif 1118 + 1119 + static void __net_exit brnf_exit_net(struct net *net) 1120 + { 1121 + struct brnf_net *brnet; 1122 + 1123 + brnet = net_generic(net, brnf_net_id); 1124 + if (brnet->enabled) { 1125 + nf_unregister_net_hooks(net, br_nf_ops, ARRAY_SIZE(br_nf_ops)); 1126 + brnet->enabled = false; 1127 + } 1128 + 1129 + #ifdef CONFIG_SYSCTL 1130 + br_netfilter_sysctl_exit_net(net, brnet); 1131 + #endif 1132 + } 1133 + 1134 + static struct pernet_operations brnf_net_ops __read_mostly = { 1135 + #ifdef CONFIG_SYSCTL 1136 + .init = brnf_init_net, 1137 + #endif 1138 + .exit = brnf_exit_net, 1139 + .id = &brnf_net_id, 1140 + .size = sizeof(struct brnf_net), 1141 + }; 1080 1142 1081 1143 static int __init br_netfilter_init(void) 1082 1144 { ··· 1167 1079 return ret; 1168 1080 } 1169 1081 1170 - #ifdef CONFIG_SYSCTL 1171 - brnf_sysctl_header = register_net_sysctl(&init_net, "net/bridge", brnf_table); 1172 - if (brnf_sysctl_header == NULL) { 1173 - printk(KERN_WARNING 1174 - "br_netfilter: can't register to sysctl.\n"); 1175 - unregister_netdevice_notifier(&brnf_notifier); 1176 - unregister_pernet_subsys(&brnf_net_ops); 1177 - return -ENOMEM; 1178 - } 1179 - #endif 1180 1082 RCU_INIT_POINTER(nf_br_ops, &br_ops); 1181 1083 printk(KERN_NOTICE "Bridge firewalling registered\n"); 1182 1084 return 0; ··· 1177 1099 RCU_INIT_POINTER(nf_br_ops, NULL); 1178 1100 unregister_netdevice_notifier(&brnf_notifier); 1179 1101 unregister_pernet_subsys(&brnf_net_ops); 1180 - #ifdef CONFIG_SYSCTL 1181 - unregister_net_sysctl_table(brnf_sysctl_header); 1182 - #endif 1183 1102 } 1184 1103 1185 1104 module_init(br_netfilter_init);
+1 -1
net/bridge/br_netfilter_ipv6.c
··· 224 224 nf_bridge = nf_bridge_alloc(skb); 225 225 if (!nf_bridge) 226 226 return NF_DROP; 227 - if (!setup_pre_routing(skb)) 227 + if (!setup_pre_routing(skb, state->net)) 228 228 return NF_DROP; 229 229 230 230 nf_bridge = nf_bridge_info_get(skb);
+2
net/bridge/netfilter/nf_conntrack_bridge.c
··· 331 331 } 332 332 if (data->vlan_present) 333 333 __vlan_hwaccel_put_tag(skb, data->vlan_proto, data->vlan_tci); 334 + else if (skb_vlan_tag_present(skb)) 335 + __vlan_hwaccel_clear_tag(skb); 334 336 335 337 skb_copy_to_linear_data_offset(skb, -ETH_HLEN, data->mac, ETH_HLEN); 336 338 skb_reset_mac_header(skb);
+1
net/ipv4/ip_options.c
··· 473 473 *info = htonl((pp_ptr-iph)<<24); 474 474 return -EINVAL; 475 475 } 476 + EXPORT_SYMBOL(__ip_options_compile); 476 477 477 478 int ip_options_compile(struct net *net, 478 479 struct ip_options *opt, struct sk_buff *skb)
+6 -389
net/ipv4/netfilter/ipt_SYNPROXY.c
··· 3 3 * Copyright (c) 2013 Patrick McHardy <kaber@trash.net> 4 4 */ 5 5 6 - #include <linux/module.h> 7 - #include <linux/skbuff.h> 8 - #include <net/tcp.h> 9 - 10 6 #include <linux/netfilter_ipv4/ip_tables.h> 11 7 #include <linux/netfilter/x_tables.h> 12 8 #include <linux/netfilter/xt_SYNPROXY.h> 13 - #include <net/netfilter/nf_conntrack.h> 14 - #include <net/netfilter/nf_conntrack_seqadj.h> 15 - #include <net/netfilter/nf_conntrack_synproxy.h> 16 - #include <net/netfilter/nf_conntrack_ecache.h> 17 9 18 - static struct iphdr * 19 - synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr, 20 - __be32 daddr) 21 - { 22 - struct iphdr *iph; 23 - 24 - skb_reset_network_header(skb); 25 - iph = skb_put(skb, sizeof(*iph)); 26 - iph->version = 4; 27 - iph->ihl = sizeof(*iph) / 4; 28 - iph->tos = 0; 29 - iph->id = 0; 30 - iph->frag_off = htons(IP_DF); 31 - iph->ttl = net->ipv4.sysctl_ip_default_ttl; 32 - iph->protocol = IPPROTO_TCP; 33 - iph->check = 0; 34 - iph->saddr = saddr; 35 - iph->daddr = daddr; 36 - 37 - return iph; 38 - } 39 - 40 - static void 41 - synproxy_send_tcp(struct net *net, 42 - const struct sk_buff *skb, struct sk_buff *nskb, 43 - struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 44 - struct iphdr *niph, struct tcphdr *nth, 45 - unsigned int tcp_hdr_size) 46 - { 47 - nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); 48 - nskb->ip_summed = CHECKSUM_PARTIAL; 49 - nskb->csum_start = (unsigned char *)nth - nskb->head; 50 - nskb->csum_offset = offsetof(struct tcphdr, check); 51 - 52 - skb_dst_set_noref(nskb, skb_dst(skb)); 53 - nskb->protocol = htons(ETH_P_IP); 54 - if (ip_route_me_harder(net, nskb, RTN_UNSPEC)) 55 - goto free_nskb; 56 - 57 - if (nfct) { 58 - nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 59 - nf_conntrack_get(nfct); 60 - } 61 - 62 - ip_local_out(net, nskb->sk, nskb); 63 - return; 64 - 65 - free_nskb: 66 - kfree_skb(nskb); 67 - } 68 - 69 - static void 70 - synproxy_send_client_synack(struct net *net, 71 - const struct sk_buff *skb, const struct tcphdr *th, 72 - const struct synproxy_options *opts) 73 - { 74 - struct sk_buff *nskb; 75 - struct iphdr *iph, *niph; 76 - struct tcphdr *nth; 77 - unsigned int tcp_hdr_size; 78 - u16 mss = opts->mss; 79 - 80 - iph = ip_hdr(skb); 81 - 82 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 83 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 84 - GFP_ATOMIC); 85 - if (nskb == NULL) 86 - return; 87 - skb_reserve(nskb, MAX_TCP_HEADER); 88 - 89 - niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 90 - 91 - skb_reset_transport_header(nskb); 92 - nth = skb_put(nskb, tcp_hdr_size); 93 - nth->source = th->dest; 94 - nth->dest = th->source; 95 - nth->seq = htonl(__cookie_v4_init_sequence(iph, th, &mss)); 96 - nth->ack_seq = htonl(ntohl(th->seq) + 1); 97 - tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 98 - if (opts->options & XT_SYNPROXY_OPT_ECN) 99 - tcp_flag_word(nth) |= TCP_FLAG_ECE; 100 - nth->doff = tcp_hdr_size / 4; 101 - nth->window = 0; 102 - nth->check = 0; 103 - nth->urg_ptr = 0; 104 - 105 - synproxy_build_options(nth, opts); 106 - 107 - synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 108 - IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 109 - } 110 - 111 - static void 112 - synproxy_send_server_syn(struct net *net, 113 - const struct sk_buff *skb, const struct tcphdr *th, 114 - const struct synproxy_options *opts, u32 recv_seq) 115 - { 116 - struct synproxy_net *snet = synproxy_pernet(net); 117 - struct sk_buff *nskb; 118 - struct iphdr *iph, *niph; 119 - struct tcphdr *nth; 120 - unsigned int tcp_hdr_size; 121 - 122 - iph = ip_hdr(skb); 123 - 124 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 125 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 126 - GFP_ATOMIC); 127 - if (nskb == NULL) 128 - return; 129 - skb_reserve(nskb, MAX_TCP_HEADER); 130 - 131 - niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 132 - 133 - skb_reset_transport_header(nskb); 134 - nth = skb_put(nskb, tcp_hdr_size); 135 - nth->source = th->source; 136 - nth->dest = th->dest; 137 - nth->seq = htonl(recv_seq - 1); 138 - /* ack_seq is used to relay our ISN to the synproxy hook to initialize 139 - * sequence number translation once a connection tracking entry exists. 140 - */ 141 - nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 142 - tcp_flag_word(nth) = TCP_FLAG_SYN; 143 - if (opts->options & XT_SYNPROXY_OPT_ECN) 144 - tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 145 - nth->doff = tcp_hdr_size / 4; 146 - nth->window = th->window; 147 - nth->check = 0; 148 - nth->urg_ptr = 0; 149 - 150 - synproxy_build_options(nth, opts); 151 - 152 - synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, 153 - niph, nth, tcp_hdr_size); 154 - } 155 - 156 - static void 157 - synproxy_send_server_ack(struct net *net, 158 - const struct ip_ct_tcp *state, 159 - const struct sk_buff *skb, const struct tcphdr *th, 160 - const struct synproxy_options *opts) 161 - { 162 - struct sk_buff *nskb; 163 - struct iphdr *iph, *niph; 164 - struct tcphdr *nth; 165 - unsigned int tcp_hdr_size; 166 - 167 - iph = ip_hdr(skb); 168 - 169 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 170 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 171 - GFP_ATOMIC); 172 - if (nskb == NULL) 173 - return; 174 - skb_reserve(nskb, MAX_TCP_HEADER); 175 - 176 - niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 177 - 178 - skb_reset_transport_header(nskb); 179 - nth = skb_put(nskb, tcp_hdr_size); 180 - nth->source = th->dest; 181 - nth->dest = th->source; 182 - nth->seq = htonl(ntohl(th->ack_seq)); 183 - nth->ack_seq = htonl(ntohl(th->seq) + 1); 184 - tcp_flag_word(nth) = TCP_FLAG_ACK; 185 - nth->doff = tcp_hdr_size / 4; 186 - nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 187 - nth->check = 0; 188 - nth->urg_ptr = 0; 189 - 190 - synproxy_build_options(nth, opts); 191 - 192 - synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); 193 - } 194 - 195 - static void 196 - synproxy_send_client_ack(struct net *net, 197 - const struct sk_buff *skb, const struct tcphdr *th, 198 - const struct synproxy_options *opts) 199 - { 200 - struct sk_buff *nskb; 201 - struct iphdr *iph, *niph; 202 - struct tcphdr *nth; 203 - unsigned int tcp_hdr_size; 204 - 205 - iph = ip_hdr(skb); 206 - 207 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 208 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 209 - GFP_ATOMIC); 210 - if (nskb == NULL) 211 - return; 212 - skb_reserve(nskb, MAX_TCP_HEADER); 213 - 214 - niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 215 - 216 - skb_reset_transport_header(nskb); 217 - nth = skb_put(nskb, tcp_hdr_size); 218 - nth->source = th->source; 219 - nth->dest = th->dest; 220 - nth->seq = htonl(ntohl(th->seq) + 1); 221 - nth->ack_seq = th->ack_seq; 222 - tcp_flag_word(nth) = TCP_FLAG_ACK; 223 - nth->doff = tcp_hdr_size / 4; 224 - nth->window = htons(ntohs(th->window) >> opts->wscale); 225 - nth->check = 0; 226 - nth->urg_ptr = 0; 227 - 228 - synproxy_build_options(nth, opts); 229 - 230 - synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 231 - IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 232 - } 233 - 234 - static bool 235 - synproxy_recv_client_ack(struct net *net, 236 - const struct sk_buff *skb, const struct tcphdr *th, 237 - struct synproxy_options *opts, u32 recv_seq) 238 - { 239 - struct synproxy_net *snet = synproxy_pernet(net); 240 - int mss; 241 - 242 - mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); 243 - if (mss == 0) { 244 - this_cpu_inc(snet->stats->cookie_invalid); 245 - return false; 246 - } 247 - 248 - this_cpu_inc(snet->stats->cookie_valid); 249 - opts->mss = mss; 250 - opts->options |= XT_SYNPROXY_OPT_MSS; 251 - 252 - if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) 253 - synproxy_check_timestamp_cookie(opts); 254 - 255 - synproxy_send_server_syn(net, skb, th, opts, recv_seq); 256 - return true; 257 - } 10 + #include <net/netfilter/nf_synproxy.h> 258 11 259 12 static unsigned int 260 13 synproxy_tg4(struct sk_buff *skb, const struct xt_action_param *par) ··· 59 306 return XT_CONTINUE; 60 307 } 61 308 62 - static unsigned int ipv4_synproxy_hook(void *priv, 63 - struct sk_buff *skb, 64 - const struct nf_hook_state *nhs) 65 - { 66 - struct net *net = nhs->net; 67 - struct synproxy_net *snet = synproxy_pernet(net); 68 - enum ip_conntrack_info ctinfo; 69 - struct nf_conn *ct; 70 - struct nf_conn_synproxy *synproxy; 71 - struct synproxy_options opts = {}; 72 - const struct ip_ct_tcp *state; 73 - struct tcphdr *th, _th; 74 - unsigned int thoff; 75 - 76 - ct = nf_ct_get(skb, &ctinfo); 77 - if (ct == NULL) 78 - return NF_ACCEPT; 79 - 80 - synproxy = nfct_synproxy(ct); 81 - if (synproxy == NULL) 82 - return NF_ACCEPT; 83 - 84 - if (nf_is_loopback_packet(skb) || 85 - ip_hdr(skb)->protocol != IPPROTO_TCP) 86 - return NF_ACCEPT; 87 - 88 - thoff = ip_hdrlen(skb); 89 - th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 90 - if (th == NULL) 91 - return NF_DROP; 92 - 93 - state = &ct->proto.tcp; 94 - switch (state->state) { 95 - case TCP_CONNTRACK_CLOSE: 96 - if (th->rst && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 97 - nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 98 - ntohl(th->seq) + 1); 99 - break; 100 - } 101 - 102 - if (!th->syn || th->ack || 103 - CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 104 - break; 105 - 106 - /* Reopened connection - reset the sequence number and timestamp 107 - * adjustments, they will get initialized once the connection is 108 - * reestablished. 109 - */ 110 - nf_ct_seqadj_init(ct, ctinfo, 0); 111 - synproxy->tsoff = 0; 112 - this_cpu_inc(snet->stats->conn_reopened); 113 - 114 - /* fall through */ 115 - case TCP_CONNTRACK_SYN_SENT: 116 - if (!synproxy_parse_options(skb, thoff, th, &opts)) 117 - return NF_DROP; 118 - 119 - if (!th->syn && th->ack && 120 - CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 121 - /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 122 - * therefore we need to add 1 to make the SYN sequence 123 - * number match the one of first SYN. 124 - */ 125 - if (synproxy_recv_client_ack(net, skb, th, &opts, 126 - ntohl(th->seq) + 1)) { 127 - this_cpu_inc(snet->stats->cookie_retrans); 128 - consume_skb(skb); 129 - return NF_STOLEN; 130 - } else { 131 - return NF_DROP; 132 - } 133 - } 134 - 135 - synproxy->isn = ntohl(th->ack_seq); 136 - if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) 137 - synproxy->its = opts.tsecr; 138 - 139 - nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 140 - break; 141 - case TCP_CONNTRACK_SYN_RECV: 142 - if (!th->syn || !th->ack) 143 - break; 144 - 145 - if (!synproxy_parse_options(skb, thoff, th, &opts)) 146 - return NF_DROP; 147 - 148 - if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) { 149 - synproxy->tsoff = opts.tsval - synproxy->its; 150 - nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 151 - } 152 - 153 - opts.options &= ~(XT_SYNPROXY_OPT_MSS | 154 - XT_SYNPROXY_OPT_WSCALE | 155 - XT_SYNPROXY_OPT_SACK_PERM); 156 - 157 - swap(opts.tsval, opts.tsecr); 158 - synproxy_send_server_ack(net, state, skb, th, &opts); 159 - 160 - nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 161 - nf_conntrack_event_cache(IPCT_SEQADJ, ct); 162 - 163 - swap(opts.tsval, opts.tsecr); 164 - synproxy_send_client_ack(net, skb, th, &opts); 165 - 166 - consume_skb(skb); 167 - return NF_STOLEN; 168 - default: 169 - break; 170 - } 171 - 172 - synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 173 - return NF_ACCEPT; 174 - } 175 - 176 - static const struct nf_hook_ops ipv4_synproxy_ops[] = { 177 - { 178 - .hook = ipv4_synproxy_hook, 179 - .pf = NFPROTO_IPV4, 180 - .hooknum = NF_INET_LOCAL_IN, 181 - .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 182 - }, 183 - { 184 - .hook = ipv4_synproxy_hook, 185 - .pf = NFPROTO_IPV4, 186 - .hooknum = NF_INET_POST_ROUTING, 187 - .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 188 - }, 189 - }; 190 - 191 309 static int synproxy_tg4_check(const struct xt_tgchk_param *par) 192 310 { 193 311 struct synproxy_net *snet = synproxy_pernet(par->net); ··· 73 449 if (err) 74 450 return err; 75 451 76 - if (snet->hook_ref4 == 0) { 77 - err = nf_register_net_hooks(par->net, ipv4_synproxy_ops, 78 - ARRAY_SIZE(ipv4_synproxy_ops)); 79 - if (err) { 80 - nf_ct_netns_put(par->net, par->family); 81 - return err; 82 - } 452 + err = nf_synproxy_ipv4_init(snet, par->net); 453 + if (err) { 454 + nf_ct_netns_put(par->net, par->family); 455 + return err; 83 456 } 84 457 85 - snet->hook_ref4++; 86 458 return err; 87 459 } 88 460 ··· 86 466 { 87 467 struct synproxy_net *snet = synproxy_pernet(par->net); 88 468 89 - snet->hook_ref4--; 90 - if (snet->hook_ref4 == 0) 91 - nf_unregister_net_hooks(par->net, ipv4_synproxy_ops, 92 - ARRAY_SIZE(ipv4_synproxy_ops)); 469 + nf_synproxy_ipv4_fini(snet, par->net); 93 470 nf_ct_netns_put(par->net, par->family); 94 471 } 95 472
+1 -1
net/ipv4/netfilter/iptable_raw.c
··· 2 2 /* 3 3 * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT . 4 4 * 5 - * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@netfilter.org> 6 6 */ 7 7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 8 #include <linux/module.h>
+1 -1
net/ipv4/netfilter/nf_nat_h323.c
··· 6 6 * Copyright (c) 2006-2012 Patrick McHardy <kaber@trash.net> 7 7 * 8 8 * Based on the 'brute force' H.323 NAT module by 9 - * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 9 + * Jozsef Kadlecsik <kadlec@netfilter.org> 10 10 */ 11 11 12 12 #include <linux/module.h>
+7 -1
net/ipv6/netfilter.c
··· 234 234 .route_me_harder = ip6_route_me_harder, 235 235 .dev_get_saddr = ipv6_dev_get_saddr, 236 236 .route = __nf_ip6_route, 237 + #if IS_ENABLED(CONFIG_SYN_COOKIES) 238 + .cookie_init_sequence = __cookie_v6_init_sequence, 239 + .cookie_v6_check = __cookie_v6_check, 240 + #endif 237 241 #endif 238 242 .route_input = ip6_route_input, 239 243 .fragment = ip6_fragment, 240 244 .reroute = nf_ip6_reroute, 241 - #if IS_MODULE(CONFIG_IPV6) 245 + #if IS_MODULE(CONFIG_IPV6) && IS_ENABLED(CONFIG_NF_DEFRAG_IPV6) 242 246 .br_defrag = nf_ct_frag6_gather, 247 + #endif 248 + #if IS_MODULE(CONFIG_IPV6) 243 249 .br_fragment = br_ip6_fragment, 244 250 #endif 245 251 };
+9 -411
net/ipv6/netfilter/ip6t_SYNPROXY.c
··· 3 3 * Copyright (c) 2013 Patrick McHardy <kaber@trash.net> 4 4 */ 5 5 6 - #include <linux/module.h> 7 - #include <linux/skbuff.h> 8 - #include <net/ip6_checksum.h> 9 - #include <net/ip6_route.h> 10 - #include <net/tcp.h> 11 - 12 6 #include <linux/netfilter_ipv6/ip6_tables.h> 13 7 #include <linux/netfilter/x_tables.h> 14 8 #include <linux/netfilter/xt_SYNPROXY.h> 15 - #include <net/netfilter/nf_conntrack.h> 16 - #include <net/netfilter/nf_conntrack_seqadj.h> 17 - #include <net/netfilter/nf_conntrack_synproxy.h> 18 - #include <net/netfilter/nf_conntrack_ecache.h> 19 9 20 - static struct ipv6hdr * 21 - synproxy_build_ip(struct net *net, struct sk_buff *skb, 22 - const struct in6_addr *saddr, 23 - const struct in6_addr *daddr) 24 - { 25 - struct ipv6hdr *iph; 26 - 27 - skb_reset_network_header(skb); 28 - iph = skb_put(skb, sizeof(*iph)); 29 - ip6_flow_hdr(iph, 0, 0); 30 - iph->hop_limit = net->ipv6.devconf_all->hop_limit; 31 - iph->nexthdr = IPPROTO_TCP; 32 - iph->saddr = *saddr; 33 - iph->daddr = *daddr; 34 - 35 - return iph; 36 - } 37 - 38 - static void 39 - synproxy_send_tcp(struct net *net, 40 - const struct sk_buff *skb, struct sk_buff *nskb, 41 - struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 42 - struct ipv6hdr *niph, struct tcphdr *nth, 43 - unsigned int tcp_hdr_size) 44 - { 45 - struct dst_entry *dst; 46 - struct flowi6 fl6; 47 - 48 - nth->check = ~tcp_v6_check(tcp_hdr_size, &niph->saddr, &niph->daddr, 0); 49 - nskb->ip_summed = CHECKSUM_PARTIAL; 50 - nskb->csum_start = (unsigned char *)nth - nskb->head; 51 - nskb->csum_offset = offsetof(struct tcphdr, check); 52 - 53 - memset(&fl6, 0, sizeof(fl6)); 54 - fl6.flowi6_proto = IPPROTO_TCP; 55 - fl6.saddr = niph->saddr; 56 - fl6.daddr = niph->daddr; 57 - fl6.fl6_sport = nth->source; 58 - fl6.fl6_dport = nth->dest; 59 - security_skb_classify_flow((struct sk_buff *)skb, flowi6_to_flowi(&fl6)); 60 - dst = ip6_route_output(net, NULL, &fl6); 61 - if (dst->error) { 62 - dst_release(dst); 63 - goto free_nskb; 64 - } 65 - dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); 66 - if (IS_ERR(dst)) 67 - goto free_nskb; 68 - 69 - skb_dst_set(nskb, dst); 70 - 71 - if (nfct) { 72 - nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 73 - nf_conntrack_get(nfct); 74 - } 75 - 76 - ip6_local_out(net, nskb->sk, nskb); 77 - return; 78 - 79 - free_nskb: 80 - kfree_skb(nskb); 81 - } 82 - 83 - static void 84 - synproxy_send_client_synack(struct net *net, 85 - const struct sk_buff *skb, const struct tcphdr *th, 86 - const struct synproxy_options *opts) 87 - { 88 - struct sk_buff *nskb; 89 - struct ipv6hdr *iph, *niph; 90 - struct tcphdr *nth; 91 - unsigned int tcp_hdr_size; 92 - u16 mss = opts->mss; 93 - 94 - iph = ipv6_hdr(skb); 95 - 96 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 97 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 98 - GFP_ATOMIC); 99 - if (nskb == NULL) 100 - return; 101 - skb_reserve(nskb, MAX_TCP_HEADER); 102 - 103 - niph = synproxy_build_ip(net, nskb, &iph->daddr, &iph->saddr); 104 - 105 - skb_reset_transport_header(nskb); 106 - nth = skb_put(nskb, tcp_hdr_size); 107 - nth->source = th->dest; 108 - nth->dest = th->source; 109 - nth->seq = htonl(__cookie_v6_init_sequence(iph, th, &mss)); 110 - nth->ack_seq = htonl(ntohl(th->seq) + 1); 111 - tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 112 - if (opts->options & XT_SYNPROXY_OPT_ECN) 113 - tcp_flag_word(nth) |= TCP_FLAG_ECE; 114 - nth->doff = tcp_hdr_size / 4; 115 - nth->window = 0; 116 - nth->check = 0; 117 - nth->urg_ptr = 0; 118 - 119 - synproxy_build_options(nth, opts); 120 - 121 - synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 122 - IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 123 - } 124 - 125 - static void 126 - synproxy_send_server_syn(struct net *net, 127 - const struct sk_buff *skb, const struct tcphdr *th, 128 - const struct synproxy_options *opts, u32 recv_seq) 129 - { 130 - struct synproxy_net *snet = synproxy_pernet(net); 131 - struct sk_buff *nskb; 132 - struct ipv6hdr *iph, *niph; 133 - struct tcphdr *nth; 134 - unsigned int tcp_hdr_size; 135 - 136 - iph = ipv6_hdr(skb); 137 - 138 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 139 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 140 - GFP_ATOMIC); 141 - if (nskb == NULL) 142 - return; 143 - skb_reserve(nskb, MAX_TCP_HEADER); 144 - 145 - niph = synproxy_build_ip(net, nskb, &iph->saddr, &iph->daddr); 146 - 147 - skb_reset_transport_header(nskb); 148 - nth = skb_put(nskb, tcp_hdr_size); 149 - nth->source = th->source; 150 - nth->dest = th->dest; 151 - nth->seq = htonl(recv_seq - 1); 152 - /* ack_seq is used to relay our ISN to the synproxy hook to initialize 153 - * sequence number translation once a connection tracking entry exists. 154 - */ 155 - nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 156 - tcp_flag_word(nth) = TCP_FLAG_SYN; 157 - if (opts->options & XT_SYNPROXY_OPT_ECN) 158 - tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 159 - nth->doff = tcp_hdr_size / 4; 160 - nth->window = th->window; 161 - nth->check = 0; 162 - nth->urg_ptr = 0; 163 - 164 - synproxy_build_options(nth, opts); 165 - 166 - synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, 167 - niph, nth, tcp_hdr_size); 168 - } 169 - 170 - static void 171 - synproxy_send_server_ack(struct net *net, 172 - const struct ip_ct_tcp *state, 173 - const struct sk_buff *skb, const struct tcphdr *th, 174 - const struct synproxy_options *opts) 175 - { 176 - struct sk_buff *nskb; 177 - struct ipv6hdr *iph, *niph; 178 - struct tcphdr *nth; 179 - unsigned int tcp_hdr_size; 180 - 181 - iph = ipv6_hdr(skb); 182 - 183 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 184 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 185 - GFP_ATOMIC); 186 - if (nskb == NULL) 187 - return; 188 - skb_reserve(nskb, MAX_TCP_HEADER); 189 - 190 - niph = synproxy_build_ip(net, nskb, &iph->daddr, &iph->saddr); 191 - 192 - skb_reset_transport_header(nskb); 193 - nth = skb_put(nskb, tcp_hdr_size); 194 - nth->source = th->dest; 195 - nth->dest = th->source; 196 - nth->seq = htonl(ntohl(th->ack_seq)); 197 - nth->ack_seq = htonl(ntohl(th->seq) + 1); 198 - tcp_flag_word(nth) = TCP_FLAG_ACK; 199 - nth->doff = tcp_hdr_size / 4; 200 - nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 201 - nth->check = 0; 202 - nth->urg_ptr = 0; 203 - 204 - synproxy_build_options(nth, opts); 205 - 206 - synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); 207 - } 208 - 209 - static void 210 - synproxy_send_client_ack(struct net *net, 211 - const struct sk_buff *skb, const struct tcphdr *th, 212 - const struct synproxy_options *opts) 213 - { 214 - struct sk_buff *nskb; 215 - struct ipv6hdr *iph, *niph; 216 - struct tcphdr *nth; 217 - unsigned int tcp_hdr_size; 218 - 219 - iph = ipv6_hdr(skb); 220 - 221 - tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 222 - nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 223 - GFP_ATOMIC); 224 - if (nskb == NULL) 225 - return; 226 - skb_reserve(nskb, MAX_TCP_HEADER); 227 - 228 - niph = synproxy_build_ip(net, nskb, &iph->saddr, &iph->daddr); 229 - 230 - skb_reset_transport_header(nskb); 231 - nth = skb_put(nskb, tcp_hdr_size); 232 - nth->source = th->source; 233 - nth->dest = th->dest; 234 - nth->seq = htonl(ntohl(th->seq) + 1); 235 - nth->ack_seq = th->ack_seq; 236 - tcp_flag_word(nth) = TCP_FLAG_ACK; 237 - nth->doff = tcp_hdr_size / 4; 238 - nth->window = htons(ntohs(th->window) >> opts->wscale); 239 - nth->check = 0; 240 - nth->urg_ptr = 0; 241 - 242 - synproxy_build_options(nth, opts); 243 - 244 - synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 245 - IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 246 - } 247 - 248 - static bool 249 - synproxy_recv_client_ack(struct net *net, 250 - const struct sk_buff *skb, const struct tcphdr *th, 251 - struct synproxy_options *opts, u32 recv_seq) 252 - { 253 - struct synproxy_net *snet = synproxy_pernet(net); 254 - int mss; 255 - 256 - mss = __cookie_v6_check(ipv6_hdr(skb), th, ntohl(th->ack_seq) - 1); 257 - if (mss == 0) { 258 - this_cpu_inc(snet->stats->cookie_invalid); 259 - return false; 260 - } 261 - 262 - this_cpu_inc(snet->stats->cookie_valid); 263 - opts->mss = mss; 264 - opts->options |= XT_SYNPROXY_OPT_MSS; 265 - 266 - if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) 267 - synproxy_check_timestamp_cookie(opts); 268 - 269 - synproxy_send_server_syn(net, skb, th, opts, recv_seq); 270 - return true; 271 - } 10 + #include <net/netfilter/nf_synproxy.h> 272 11 273 12 static unsigned int 274 13 synproxy_tg6(struct sk_buff *skb, const struct xt_action_param *par) ··· 43 304 XT_SYNPROXY_OPT_SACK_PERM | 44 305 XT_SYNPROXY_OPT_ECN); 45 306 46 - synproxy_send_client_synack(net, skb, th, &opts); 307 + synproxy_send_client_synack_ipv6(net, skb, th, &opts); 47 308 consume_skb(skb); 48 309 return NF_STOLEN; 49 310 50 311 } else if (th->ack && !(th->fin || th->rst || th->syn)) { 51 312 /* ACK from client */ 52 - if (synproxy_recv_client_ack(net, skb, th, &opts, ntohl(th->seq))) { 313 + if (synproxy_recv_client_ack_ipv6(net, skb, th, &opts, 314 + ntohl(th->seq))) { 53 315 consume_skb(skb); 54 316 return NF_STOLEN; 55 317 } else { ··· 60 320 61 321 return XT_CONTINUE; 62 322 } 63 - 64 - static unsigned int ipv6_synproxy_hook(void *priv, 65 - struct sk_buff *skb, 66 - const struct nf_hook_state *nhs) 67 - { 68 - struct net *net = nhs->net; 69 - struct synproxy_net *snet = synproxy_pernet(net); 70 - enum ip_conntrack_info ctinfo; 71 - struct nf_conn *ct; 72 - struct nf_conn_synproxy *synproxy; 73 - struct synproxy_options opts = {}; 74 - const struct ip_ct_tcp *state; 75 - struct tcphdr *th, _th; 76 - __be16 frag_off; 77 - u8 nexthdr; 78 - int thoff; 79 - 80 - ct = nf_ct_get(skb, &ctinfo); 81 - if (ct == NULL) 82 - return NF_ACCEPT; 83 - 84 - synproxy = nfct_synproxy(ct); 85 - if (synproxy == NULL) 86 - return NF_ACCEPT; 87 - 88 - if (nf_is_loopback_packet(skb)) 89 - return NF_ACCEPT; 90 - 91 - nexthdr = ipv6_hdr(skb)->nexthdr; 92 - thoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, 93 - &frag_off); 94 - if (thoff < 0 || nexthdr != IPPROTO_TCP) 95 - return NF_ACCEPT; 96 - 97 - th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 98 - if (th == NULL) 99 - return NF_DROP; 100 - 101 - state = &ct->proto.tcp; 102 - switch (state->state) { 103 - case TCP_CONNTRACK_CLOSE: 104 - if (th->rst && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 105 - nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 106 - ntohl(th->seq) + 1); 107 - break; 108 - } 109 - 110 - if (!th->syn || th->ack || 111 - CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 112 - break; 113 - 114 - /* Reopened connection - reset the sequence number and timestamp 115 - * adjustments, they will get initialized once the connection is 116 - * reestablished. 117 - */ 118 - nf_ct_seqadj_init(ct, ctinfo, 0); 119 - synproxy->tsoff = 0; 120 - this_cpu_inc(snet->stats->conn_reopened); 121 - 122 - /* fall through */ 123 - case TCP_CONNTRACK_SYN_SENT: 124 - if (!synproxy_parse_options(skb, thoff, th, &opts)) 125 - return NF_DROP; 126 - 127 - if (!th->syn && th->ack && 128 - CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 129 - /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 130 - * therefore we need to add 1 to make the SYN sequence 131 - * number match the one of first SYN. 132 - */ 133 - if (synproxy_recv_client_ack(net, skb, th, &opts, 134 - ntohl(th->seq) + 1)) { 135 - this_cpu_inc(snet->stats->cookie_retrans); 136 - consume_skb(skb); 137 - return NF_STOLEN; 138 - } else { 139 - return NF_DROP; 140 - } 141 - } 142 - 143 - synproxy->isn = ntohl(th->ack_seq); 144 - if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) 145 - synproxy->its = opts.tsecr; 146 - 147 - nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 148 - break; 149 - case TCP_CONNTRACK_SYN_RECV: 150 - if (!th->syn || !th->ack) 151 - break; 152 - 153 - if (!synproxy_parse_options(skb, thoff, th, &opts)) 154 - return NF_DROP; 155 - 156 - if (opts.options & XT_SYNPROXY_OPT_TIMESTAMP) { 157 - synproxy->tsoff = opts.tsval - synproxy->its; 158 - nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 159 - } 160 - 161 - opts.options &= ~(XT_SYNPROXY_OPT_MSS | 162 - XT_SYNPROXY_OPT_WSCALE | 163 - XT_SYNPROXY_OPT_SACK_PERM); 164 - 165 - swap(opts.tsval, opts.tsecr); 166 - synproxy_send_server_ack(net, state, skb, th, &opts); 167 - 168 - nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 169 - nf_conntrack_event_cache(IPCT_SEQADJ, ct); 170 - 171 - swap(opts.tsval, opts.tsecr); 172 - synproxy_send_client_ack(net, skb, th, &opts); 173 - 174 - consume_skb(skb); 175 - return NF_STOLEN; 176 - default: 177 - break; 178 - } 179 - 180 - synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 181 - return NF_ACCEPT; 182 - } 183 - 184 - static const struct nf_hook_ops ipv6_synproxy_ops[] = { 185 - { 186 - .hook = ipv6_synproxy_hook, 187 - .pf = NFPROTO_IPV6, 188 - .hooknum = NF_INET_LOCAL_IN, 189 - .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 190 - }, 191 - { 192 - .hook = ipv6_synproxy_hook, 193 - .pf = NFPROTO_IPV6, 194 - .hooknum = NF_INET_POST_ROUTING, 195 - .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 196 - }, 197 - }; 198 323 199 324 static int synproxy_tg6_check(const struct xt_tgchk_param *par) 200 325 { ··· 76 471 if (err) 77 472 return err; 78 473 79 - if (snet->hook_ref6 == 0) { 80 - err = nf_register_net_hooks(par->net, ipv6_synproxy_ops, 81 - ARRAY_SIZE(ipv6_synproxy_ops)); 82 - if (err) { 83 - nf_ct_netns_put(par->net, par->family); 84 - return err; 85 - } 474 + err = nf_synproxy_ipv6_init(snet, par->net); 475 + if (err) { 476 + nf_ct_netns_put(par->net, par->family); 477 + return err; 86 478 } 87 479 88 - snet->hook_ref6++; 89 480 return err; 90 481 } 91 482 ··· 89 488 { 90 489 struct synproxy_net *snet = synproxy_pernet(par->net); 91 490 92 - snet->hook_ref6--; 93 - if (snet->hook_ref6 == 0) 94 - nf_unregister_net_hooks(par->net, ipv6_synproxy_ops, 95 - ARRAY_SIZE(ipv6_synproxy_ops)); 491 + nf_synproxy_ipv6_fini(snet, par->net); 96 492 nf_ct_netns_put(par->net, par->family); 97 493 } 98 494
+1 -1
net/ipv6/netfilter/ip6table_raw.c
··· 2 2 /* 3 3 * IPv6 raw table, a port of the IPv4 raw table to IPv6 4 4 * 5 - * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 + * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@netfilter.org> 6 6 */ 7 7 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 8 8 #include <linux/module.h>
+1 -2
net/netfilter/ipset/ip_set_bitmap_gen.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 #ifndef __IP_SET_BITMAP_IP_GEN_H 6 5 #define __IP_SET_BITMAP_IP_GEN_H
+2 -2
net/netfilter/ipset/ip_set_bitmap_ip.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 3 3 * Patrick Schaaf <bof@bof.de> 4 - * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4 + * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> 5 5 */ 6 6 7 7 /* Kernel module implementing an IP set type: the bitmap:ip type */ ··· 28 28 #define IPSET_TYPE_REV_MAX 3 /* skbinfo support added */ 29 29 30 30 MODULE_LICENSE("GPL"); 31 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 31 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 32 32 IP_SET_MODULE_DESC("bitmap:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 33 33 MODULE_ALIAS("ip_set_bitmap:ip"); 34 34
+1 -2
net/netfilter/ipset/ip_set_bitmap_ipmac.c
··· 2 2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 3 3 * Patrick Schaaf <bof@bof.de> 4 4 * Martin Josefsson <gandalf@wlug.westbo.se> 5 - * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 6 5 */ 7 6 8 7 /* Kernel module implementing an IP set type: the bitmap:ip,mac type */ ··· 27 28 #define IPSET_TYPE_REV_MAX 3 /* skbinfo support added */ 28 29 29 30 MODULE_LICENSE("GPL"); 30 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 31 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 31 32 IP_SET_MODULE_DESC("bitmap:ip,mac", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 32 33 MODULE_ALIAS("ip_set_bitmap:ip,mac"); 33 34
+2 -3
net/netfilter/ipset/ip_set_bitmap_port.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the bitmap:port type */ 6 5 ··· 22 23 #define IPSET_TYPE_REV_MAX 3 /* skbinfo support added */ 23 24 24 25 MODULE_LICENSE("GPL"); 25 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 26 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 26 27 IP_SET_MODULE_DESC("bitmap:port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 27 28 MODULE_ALIAS("ip_set_bitmap:port"); 28 29
+35 -62
net/netfilter/ipset/ip_set_core.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 3 3 * Patrick Schaaf <bof@bof.de> 4 - * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4 + * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> 5 5 */ 6 6 7 7 /* Kernel module for IP set management */ ··· 48 48 module_param(max_sets, int, 0600); 49 49 MODULE_PARM_DESC(max_sets, "maximal number of sets"); 50 50 MODULE_LICENSE("GPL"); 51 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 51 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 52 52 MODULE_DESCRIPTION("core IP set support"); 53 53 MODULE_ALIAS_NFNL_SUBSYS(NFNL_SUBSYS_IPSET); 54 54 ··· 1290 1290 struct nlattr *attr = (void *)nlh + min_len; 1291 1291 u32 dump_type; 1292 1292 ip_set_id_t index; 1293 + int ret; 1293 1294 1294 - /* Second pass, so parser can't fail */ 1295 - nla_parse_deprecated(cda, IPSET_ATTR_CMD_MAX, attr, 1296 - nlh->nlmsg_len - min_len, ip_set_setname_policy, 1297 - NULL); 1295 + ret = nla_parse_deprecated(cda, IPSET_ATTR_CMD_MAX, attr, 1296 + nlh->nlmsg_len - min_len, 1297 + ip_set_setname_policy, NULL); 1298 + if (ret) 1299 + return ret; 1298 1300 1299 1301 cb->args[IPSET_CB_PROTO] = nla_get_u8(cda[IPSET_ATTR_PROTOCOL]); 1300 1302 if (cda[IPSET_ATTR_SETNAME]) { ··· 1543 1541 memcpy(&errmsg->msg, nlh, nlh->nlmsg_len); 1544 1542 cmdattr = (void *)&errmsg->msg + min_len; 1545 1543 1546 - nla_parse_deprecated(cda, IPSET_ATTR_CMD_MAX, cmdattr, 1547 - nlh->nlmsg_len - min_len, 1548 - ip_set_adt_policy, NULL); 1544 + ret = nla_parse_deprecated(cda, IPSET_ATTR_CMD_MAX, cmdattr, 1545 + nlh->nlmsg_len - min_len, 1546 + ip_set_adt_policy, NULL); 1549 1547 1548 + if (ret) { 1549 + nlmsg_free(skb2); 1550 + return ret; 1551 + } 1550 1552 errline = nla_data(cda[IPSET_ATTR_LINENO]); 1551 1553 1552 1554 *errline = lineno; ··· 1564 1558 return ret; 1565 1559 } 1566 1560 1567 - static int ip_set_uadd(struct net *net, struct sock *ctnl, struct sk_buff *skb, 1568 - const struct nlmsghdr *nlh, 1569 - const struct nlattr * const attr[], 1570 - struct netlink_ext_ack *extack) 1561 + static int ip_set_ad(struct net *net, struct sock *ctnl, 1562 + struct sk_buff *skb, 1563 + enum ipset_adt adt, 1564 + const struct nlmsghdr *nlh, 1565 + const struct nlattr * const attr[], 1566 + struct netlink_ext_ack *extack) 1571 1567 { 1572 1568 struct ip_set_net *inst = ip_set_pernet(net); 1573 1569 struct ip_set *set; ··· 1598 1590 if (attr[IPSET_ATTR_DATA]) { 1599 1591 if (nla_parse_nested_deprecated(tb, IPSET_ATTR_ADT_MAX, attr[IPSET_ATTR_DATA], set->type->adt_policy, NULL)) 1600 1592 return -IPSET_ERR_PROTOCOL; 1601 - ret = call_ad(ctnl, skb, set, tb, IPSET_ADD, flags, 1593 + ret = call_ad(ctnl, skb, set, tb, adt, flags, 1602 1594 use_lineno); 1603 1595 } else { 1604 1596 int nla_rem; 1605 1597 1606 1598 nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) { 1607 - memset(tb, 0, sizeof(tb)); 1608 1599 if (nla_type(nla) != IPSET_ATTR_DATA || 1609 1600 !flag_nested(nla) || 1610 1601 nla_parse_nested_deprecated(tb, IPSET_ATTR_ADT_MAX, nla, set->type->adt_policy, NULL)) 1611 1602 return -IPSET_ERR_PROTOCOL; 1612 - ret = call_ad(ctnl, skb, set, tb, IPSET_ADD, 1603 + ret = call_ad(ctnl, skb, set, tb, adt, 1613 1604 flags, use_lineno); 1614 1605 if (ret < 0) 1615 1606 return ret; ··· 1617 1610 return ret; 1618 1611 } 1619 1612 1620 - static int ip_set_udel(struct net *net, struct sock *ctnl, struct sk_buff *skb, 1621 - const struct nlmsghdr *nlh, 1613 + static int ip_set_uadd(struct net *net, struct sock *ctnl, 1614 + struct sk_buff *skb, const struct nlmsghdr *nlh, 1622 1615 const struct nlattr * const attr[], 1623 1616 struct netlink_ext_ack *extack) 1624 1617 { 1625 - struct ip_set_net *inst = ip_set_pernet(net); 1626 - struct ip_set *set; 1627 - struct nlattr *tb[IPSET_ATTR_ADT_MAX + 1] = {}; 1628 - const struct nlattr *nla; 1629 - u32 flags = flag_exist(nlh); 1630 - bool use_lineno; 1631 - int ret = 0; 1618 + return ip_set_ad(net, ctnl, skb, 1619 + IPSET_ADD, nlh, attr, extack); 1620 + } 1632 1621 1633 - if (unlikely(protocol_min_failed(attr) || 1634 - !attr[IPSET_ATTR_SETNAME] || 1635 - !((attr[IPSET_ATTR_DATA] != NULL) ^ 1636 - (attr[IPSET_ATTR_ADT] != NULL)) || 1637 - (attr[IPSET_ATTR_DATA] && 1638 - !flag_nested(attr[IPSET_ATTR_DATA])) || 1639 - (attr[IPSET_ATTR_ADT] && 1640 - (!flag_nested(attr[IPSET_ATTR_ADT]) || 1641 - !attr[IPSET_ATTR_LINENO])))) 1642 - return -IPSET_ERR_PROTOCOL; 1643 - 1644 - set = find_set(inst, nla_data(attr[IPSET_ATTR_SETNAME])); 1645 - if (!set) 1646 - return -ENOENT; 1647 - 1648 - use_lineno = !!attr[IPSET_ATTR_LINENO]; 1649 - if (attr[IPSET_ATTR_DATA]) { 1650 - if (nla_parse_nested_deprecated(tb, IPSET_ATTR_ADT_MAX, attr[IPSET_ATTR_DATA], set->type->adt_policy, NULL)) 1651 - return -IPSET_ERR_PROTOCOL; 1652 - ret = call_ad(ctnl, skb, set, tb, IPSET_DEL, flags, 1653 - use_lineno); 1654 - } else { 1655 - int nla_rem; 1656 - 1657 - nla_for_each_nested(nla, attr[IPSET_ATTR_ADT], nla_rem) { 1658 - memset(tb, 0, sizeof(*tb)); 1659 - if (nla_type(nla) != IPSET_ATTR_DATA || 1660 - !flag_nested(nla) || 1661 - nla_parse_nested_deprecated(tb, IPSET_ATTR_ADT_MAX, nla, set->type->adt_policy, NULL)) 1662 - return -IPSET_ERR_PROTOCOL; 1663 - ret = call_ad(ctnl, skb, set, tb, IPSET_DEL, 1664 - flags, use_lineno); 1665 - if (ret < 0) 1666 - return ret; 1667 - } 1668 - } 1669 - return ret; 1622 + static int ip_set_udel(struct net *net, struct sock *ctnl, 1623 + struct sk_buff *skb, const struct nlmsghdr *nlh, 1624 + const struct nlattr * const attr[], 1625 + struct netlink_ext_ack *extack) 1626 + { 1627 + return ip_set_ad(net, ctnl, skb, 1628 + IPSET_DEL, nlh, attr, extack); 1670 1629 } 1671 1630 1672 1631 static int ip_set_utest(struct net *net, struct sock *ctnl, struct sk_buff *skb,
+5 -1
net/netfilter/ipset/ip_set_getport.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 2 + /* Copyright (C) 2003-2011 Jozsef Kadlecsik <kadlec@netfilter.org> 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 as 6 + * published by the Free Software Foundation. 3 7 */ 4 8 5 9 /* Get Layer-4 data from the packets */
+2 -3
net/netfilter/ipset/ip_set_hash_gen.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 - /* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 #ifndef _IP_SET_HASH_GEN_H 6 5 #define _IP_SET_HASH_GEN_H ··· 621 622 goto cleanup; 622 623 } 623 624 m->size = AHASH_INIT_SIZE; 624 - extsize = ext_size(AHASH_INIT_SIZE, dsize); 625 + extsize += ext_size(AHASH_INIT_SIZE, dsize); 625 626 RCU_INIT_POINTER(hbucket(t, key), m); 626 627 } else if (m->pos >= m->size) { 627 628 struct hbucket *ht;
+2 -3
net/netfilter/ipset/ip_set_hash_ip.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:ip type */ 6 5 ··· 26 27 #define IPSET_TYPE_REV_MAX 4 /* skbinfo support */ 27 28 28 29 MODULE_LICENSE("GPL"); 29 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 30 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 30 31 IP_SET_MODULE_DESC("hash:ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 31 32 MODULE_ALIAS("ip_set_hash:ip"); 32 33
+1 -3
net/netfilter/ipset/ip_set_hash_ipmark.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - * Copyright (C) 2013 Smoothwall Ltd. <vytas.dauksa@smoothwall.net> 4 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 5 3 6 4 /* Kernel module implementing an IP set type: the hash:ip,mark type */ 7 5
+2 -3
net/netfilter/ipset/ip_set_hash_ipport.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:ip,port type */ 6 5 ··· 28 29 #define IPSET_TYPE_REV_MAX 5 /* skbinfo support added */ 29 30 30 31 MODULE_LICENSE("GPL"); 31 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 32 33 IP_SET_MODULE_DESC("hash:ip,port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 33 34 MODULE_ALIAS("ip_set_hash:ip,port"); 34 35
+2 -3
net/netfilter/ipset/ip_set_hash_ipportip.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:ip,port,ip type */ 6 5 ··· 28 29 #define IPSET_TYPE_REV_MAX 5 /* skbinfo support added */ 29 30 30 31 MODULE_LICENSE("GPL"); 31 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 32 33 IP_SET_MODULE_DESC("hash:ip,port,ip", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 33 34 MODULE_ALIAS("ip_set_hash:ip,port,ip"); 34 35
+2 -3
net/netfilter/ipset/ip_set_hash_ipportnet.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:ip,port,net type */ 6 5 ··· 30 31 #define IPSET_TYPE_REV_MAX 7 /* skbinfo support added */ 31 32 32 33 MODULE_LICENSE("GPL"); 33 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 34 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 34 35 IP_SET_MODULE_DESC("hash:ip,port,net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 35 36 MODULE_ALIAS("ip_set_hash:ip,port,net"); 36 37
+2 -3
net/netfilter/ipset/ip_set_hash_mac.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2014 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2014 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:mac type */ 6 5 ··· 19 20 #define IPSET_TYPE_REV_MAX 0 20 21 21 22 MODULE_LICENSE("GPL"); 22 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 23 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 23 24 IP_SET_MODULE_DESC("hash:mac", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 24 25 MODULE_ALIAS("ip_set_hash:mac"); 25 26
+2 -3
net/netfilter/ipset/ip_set_hash_net.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:net type */ 6 5 ··· 27 28 #define IPSET_TYPE_REV_MAX 6 /* skbinfo mapping support added */ 28 29 29 30 MODULE_LICENSE("GPL"); 30 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 31 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 31 32 IP_SET_MODULE_DESC("hash:net", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 32 33 MODULE_ALIAS("ip_set_hash:net"); 33 34
+2 -3
net/netfilter/ipset/ip_set_hash_netiface.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2011-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2011-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:net,iface type */ 6 5 ··· 28 29 #define IPSET_TYPE_REV_MAX 6 /* skbinfo support added */ 29 30 30 31 MODULE_LICENSE("GPL"); 31 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 32 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 32 33 IP_SET_MODULE_DESC("hash:net,iface", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 33 34 MODULE_ALIAS("ip_set_hash:net,iface"); 34 35
+1 -1
net/netfilter/ipset/ip_set_hash_netnet.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> 3 3 * Copyright (C) 2013 Oliver Smith <oliver@8.c.9.b.0.7.4.0.1.0.0.2.ip6.arpa> 4 4 */ 5 5
+2 -3
net/netfilter/ipset/ip_set_hash_netport.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:net,port type */ 6 5 ··· 29 30 #define IPSET_TYPE_REV_MAX 7 /* skbinfo support added */ 30 31 31 32 MODULE_LICENSE("GPL"); 32 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 33 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 33 34 IP_SET_MODULE_DESC("hash:net,port", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 34 35 MODULE_ALIAS("ip_set_hash:net,port"); 35 36
+1 -2
net/netfilter/ipset/ip_set_hash_netportnet.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the hash:ip,port,net type */ 6 5
+2 -3
net/netfilter/ipset/ip_set_list_set.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 - /* Copyright (C) 2008-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 3 - */ 2 + /* Copyright (C) 2008-2013 Jozsef Kadlecsik <kadlec@netfilter.org> */ 4 3 5 4 /* Kernel module implementing an IP set type: the list:set type */ 6 5 ··· 18 19 #define IPSET_TYPE_REV_MAX 3 /* skbinfo support added */ 19 20 20 21 MODULE_LICENSE("GPL"); 21 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 22 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 22 23 IP_SET_MODULE_DESC("list:set", IPSET_TYPE_REV_MIN, IPSET_TYPE_REV_MAX); 23 24 MODULE_ALIAS("ip_set_list:set"); 24 25
+13 -12
net/netfilter/nf_conntrack_core.c
··· 749 749 continue; 750 750 } 751 751 752 - if (nf_ct_is_dying(ct)) 753 - continue; 754 - 755 752 if (nf_ct_key_equal(h, tuple, zone, net)) 756 753 return h; 757 754 } ··· 774 777 struct nf_conn *ct; 775 778 776 779 rcu_read_lock(); 777 - begin: 780 + 778 781 h = ____nf_conntrack_find(net, zone, tuple, hash); 779 782 if (h) { 783 + /* We have a candidate that matches the tuple we're interested 784 + * in, try to obtain a reference and re-check tuple 785 + */ 780 786 ct = nf_ct_tuplehash_to_ctrack(h); 781 - if (unlikely(nf_ct_is_dying(ct) || 782 - !atomic_inc_not_zero(&ct->ct_general.use))) 783 - h = NULL; 784 - else { 785 - if (unlikely(!nf_ct_key_equal(h, tuple, zone, net))) { 786 - nf_ct_put(ct); 787 - goto begin; 788 - } 787 + if (likely(atomic_inc_not_zero(&ct->ct_general.use))) { 788 + if (likely(nf_ct_key_equal(h, tuple, zone, net))) 789 + goto found; 790 + 791 + /* TYPESAFE_BY_RCU recycled the candidate */ 792 + nf_ct_put(ct); 789 793 } 794 + 795 + h = NULL; 790 796 } 797 + found: 791 798 rcu_read_unlock(); 792 799 793 800 return h;
+1 -1
net/netfilter/nf_conntrack_h323_main.c
··· 6 6 * Copyright (c) 2006-2012 Patrick McHardy <kaber@trash.net> 7 7 * 8 8 * Based on the 'brute force' H.323 connection tracking module by 9 - * Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 9 + * Jozsef Kadlecsik <kadlec@netfilter.org> 10 10 * 11 11 * For more information, please see http://nath323.sourceforge.net/ 12 12 */
+1 -1
net/netfilter/nf_conntrack_proto_tcp.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* (C) 1999-2001 Paul `Rusty' Russell 3 3 * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org> 4 - * (C) 2002-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 4 + * (C) 2002-2013 Jozsef Kadlecsik <kadlec@netfilter.org> 5 5 * (C) 2006-2012 Patrick McHardy <kaber@trash.net> 6 6 */ 7 7
+859 -37
net/netfilter/nf_synproxy_core.c
··· 10 10 #include <net/netns/generic.h> 11 11 #include <linux/proc_fs.h> 12 12 13 - #include <linux/netfilter_ipv4/ip_tables.h> 14 - #include <linux/netfilter/x_tables.h> 15 - #include <linux/netfilter/xt_tcpudp.h> 16 - #include <linux/netfilter/xt_SYNPROXY.h> 13 + #include <linux/netfilter_ipv6.h> 14 + #include <linux/netfilter/nf_SYNPROXY.h> 17 15 18 16 #include <net/netfilter/nf_conntrack.h> 17 + #include <net/netfilter/nf_conntrack_ecache.h> 19 18 #include <net/netfilter/nf_conntrack_extend.h> 20 19 #include <net/netfilter/nf_conntrack_seqadj.h> 21 20 #include <net/netfilter/nf_conntrack_synproxy.h> 22 21 #include <net/netfilter/nf_conntrack_zones.h> 22 + #include <net/netfilter/nf_synproxy.h> 23 23 24 24 unsigned int synproxy_net_id; 25 25 EXPORT_SYMBOL_GPL(synproxy_net_id); ··· 57 57 case TCPOPT_MSS: 58 58 if (opsize == TCPOLEN_MSS) { 59 59 opts->mss = get_unaligned_be16(ptr); 60 - opts->options |= XT_SYNPROXY_OPT_MSS; 60 + opts->options |= NF_SYNPROXY_OPT_MSS; 61 61 } 62 62 break; 63 63 case TCPOPT_WINDOW: ··· 65 65 opts->wscale = *ptr; 66 66 if (opts->wscale > TCP_MAX_WSCALE) 67 67 opts->wscale = TCP_MAX_WSCALE; 68 - opts->options |= XT_SYNPROXY_OPT_WSCALE; 68 + opts->options |= NF_SYNPROXY_OPT_WSCALE; 69 69 } 70 70 break; 71 71 case TCPOPT_TIMESTAMP: 72 72 if (opsize == TCPOLEN_TIMESTAMP) { 73 73 opts->tsval = get_unaligned_be32(ptr); 74 74 opts->tsecr = get_unaligned_be32(ptr + 4); 75 - opts->options |= XT_SYNPROXY_OPT_TIMESTAMP; 75 + opts->options |= NF_SYNPROXY_OPT_TIMESTAMP; 76 76 } 77 77 break; 78 78 case TCPOPT_SACK_PERM: 79 79 if (opsize == TCPOLEN_SACK_PERM) 80 - opts->options |= XT_SYNPROXY_OPT_SACK_PERM; 80 + opts->options |= NF_SYNPROXY_OPT_SACK_PERM; 81 81 break; 82 82 } 83 83 ··· 89 89 } 90 90 EXPORT_SYMBOL_GPL(synproxy_parse_options); 91 91 92 - unsigned int synproxy_options_size(const struct synproxy_options *opts) 92 + static unsigned int 93 + synproxy_options_size(const struct synproxy_options *opts) 93 94 { 94 95 unsigned int size = 0; 95 96 96 - if (opts->options & XT_SYNPROXY_OPT_MSS) 97 + if (opts->options & NF_SYNPROXY_OPT_MSS) 97 98 size += TCPOLEN_MSS_ALIGNED; 98 - if (opts->options & XT_SYNPROXY_OPT_TIMESTAMP) 99 + if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 99 100 size += TCPOLEN_TSTAMP_ALIGNED; 100 - else if (opts->options & XT_SYNPROXY_OPT_SACK_PERM) 101 + else if (opts->options & NF_SYNPROXY_OPT_SACK_PERM) 101 102 size += TCPOLEN_SACKPERM_ALIGNED; 102 - if (opts->options & XT_SYNPROXY_OPT_WSCALE) 103 + if (opts->options & NF_SYNPROXY_OPT_WSCALE) 103 104 size += TCPOLEN_WSCALE_ALIGNED; 104 105 105 106 return size; 106 107 } 107 - EXPORT_SYMBOL_GPL(synproxy_options_size); 108 108 109 - void 109 + static void 110 110 synproxy_build_options(struct tcphdr *th, const struct synproxy_options *opts) 111 111 { 112 112 __be32 *ptr = (__be32 *)(th + 1); 113 113 u8 options = opts->options; 114 114 115 - if (options & XT_SYNPROXY_OPT_MSS) 115 + if (options & NF_SYNPROXY_OPT_MSS) 116 116 *ptr++ = htonl((TCPOPT_MSS << 24) | 117 117 (TCPOLEN_MSS << 16) | 118 118 opts->mss); 119 119 120 - if (options & XT_SYNPROXY_OPT_TIMESTAMP) { 121 - if (options & XT_SYNPROXY_OPT_SACK_PERM) 120 + if (options & NF_SYNPROXY_OPT_TIMESTAMP) { 121 + if (options & NF_SYNPROXY_OPT_SACK_PERM) 122 122 *ptr++ = htonl((TCPOPT_SACK_PERM << 24) | 123 123 (TCPOLEN_SACK_PERM << 16) | 124 124 (TCPOPT_TIMESTAMP << 8) | ··· 131 131 132 132 *ptr++ = htonl(opts->tsval); 133 133 *ptr++ = htonl(opts->tsecr); 134 - } else if (options & XT_SYNPROXY_OPT_SACK_PERM) 134 + } else if (options & NF_SYNPROXY_OPT_SACK_PERM) 135 135 *ptr++ = htonl((TCPOPT_NOP << 24) | 136 136 (TCPOPT_NOP << 16) | 137 137 (TCPOPT_SACK_PERM << 8) | 138 138 TCPOLEN_SACK_PERM); 139 139 140 - if (options & XT_SYNPROXY_OPT_WSCALE) 140 + if (options & NF_SYNPROXY_OPT_WSCALE) 141 141 *ptr++ = htonl((TCPOPT_NOP << 24) | 142 142 (TCPOPT_WINDOW << 16) | 143 143 (TCPOLEN_WINDOW << 8) | 144 144 opts->wscale); 145 145 } 146 - EXPORT_SYMBOL_GPL(synproxy_build_options); 147 146 148 - void synproxy_init_timestamp_cookie(const struct xt_synproxy_info *info, 147 + void synproxy_init_timestamp_cookie(const struct nf_synproxy_info *info, 149 148 struct synproxy_options *opts) 150 149 { 151 150 opts->tsecr = opts->tsval; 152 151 opts->tsval = tcp_time_stamp_raw() & ~0x3f; 153 152 154 - if (opts->options & XT_SYNPROXY_OPT_WSCALE) { 153 + if (opts->options & NF_SYNPROXY_OPT_WSCALE) { 155 154 opts->tsval |= opts->wscale; 156 155 opts->wscale = info->wscale; 157 156 } else 158 157 opts->tsval |= 0xf; 159 158 160 - if (opts->options & XT_SYNPROXY_OPT_SACK_PERM) 159 + if (opts->options & NF_SYNPROXY_OPT_SACK_PERM) 161 160 opts->tsval |= 1 << 4; 162 161 163 - if (opts->options & XT_SYNPROXY_OPT_ECN) 162 + if (opts->options & NF_SYNPROXY_OPT_ECN) 164 163 opts->tsval |= 1 << 5; 165 164 } 166 165 EXPORT_SYMBOL_GPL(synproxy_init_timestamp_cookie); 167 166 168 - void synproxy_check_timestamp_cookie(struct synproxy_options *opts) 167 + static void 168 + synproxy_check_timestamp_cookie(struct synproxy_options *opts) 169 169 { 170 170 opts->wscale = opts->tsecr & 0xf; 171 171 if (opts->wscale != 0xf) 172 - opts->options |= XT_SYNPROXY_OPT_WSCALE; 172 + opts->options |= NF_SYNPROXY_OPT_WSCALE; 173 173 174 - opts->options |= opts->tsecr & (1 << 4) ? XT_SYNPROXY_OPT_SACK_PERM : 0; 174 + opts->options |= opts->tsecr & (1 << 4) ? NF_SYNPROXY_OPT_SACK_PERM : 0; 175 175 176 - opts->options |= opts->tsecr & (1 << 5) ? XT_SYNPROXY_OPT_ECN : 0; 176 + opts->options |= opts->tsecr & (1 << 5) ? NF_SYNPROXY_OPT_ECN : 0; 177 177 } 178 - EXPORT_SYMBOL_GPL(synproxy_check_timestamp_cookie); 179 178 180 - unsigned int synproxy_tstamp_adjust(struct sk_buff *skb, 181 - unsigned int protoff, 182 - struct tcphdr *th, 183 - struct nf_conn *ct, 184 - enum ip_conntrack_info ctinfo, 185 - const struct nf_conn_synproxy *synproxy) 179 + static unsigned int 180 + synproxy_tstamp_adjust(struct sk_buff *skb, unsigned int protoff, 181 + struct tcphdr *th, struct nf_conn *ct, 182 + enum ip_conntrack_info ctinfo, 183 + const struct nf_conn_synproxy *synproxy) 186 184 { 187 185 unsigned int optoff, optend; 188 186 __be32 *ptr, old; ··· 230 232 } 231 233 return 1; 232 234 } 233 - EXPORT_SYMBOL_GPL(synproxy_tstamp_adjust); 234 235 235 236 static struct nf_ct_ext_type nf_ct_synproxy_extend __read_mostly = { 236 237 .len = sizeof(struct nf_conn_synproxy), ··· 409 412 410 413 module_init(synproxy_core_init); 411 414 module_exit(synproxy_core_exit); 415 + 416 + static struct iphdr * 417 + synproxy_build_ip(struct net *net, struct sk_buff *skb, __be32 saddr, 418 + __be32 daddr) 419 + { 420 + struct iphdr *iph; 421 + 422 + skb_reset_network_header(skb); 423 + iph = skb_put(skb, sizeof(*iph)); 424 + iph->version = 4; 425 + iph->ihl = sizeof(*iph) / 4; 426 + iph->tos = 0; 427 + iph->id = 0; 428 + iph->frag_off = htons(IP_DF); 429 + iph->ttl = net->ipv4.sysctl_ip_default_ttl; 430 + iph->protocol = IPPROTO_TCP; 431 + iph->check = 0; 432 + iph->saddr = saddr; 433 + iph->daddr = daddr; 434 + 435 + return iph; 436 + } 437 + 438 + static void 439 + synproxy_send_tcp(struct net *net, 440 + const struct sk_buff *skb, struct sk_buff *nskb, 441 + struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 442 + struct iphdr *niph, struct tcphdr *nth, 443 + unsigned int tcp_hdr_size) 444 + { 445 + nth->check = ~tcp_v4_check(tcp_hdr_size, niph->saddr, niph->daddr, 0); 446 + nskb->ip_summed = CHECKSUM_PARTIAL; 447 + nskb->csum_start = (unsigned char *)nth - nskb->head; 448 + nskb->csum_offset = offsetof(struct tcphdr, check); 449 + 450 + skb_dst_set_noref(nskb, skb_dst(skb)); 451 + nskb->protocol = htons(ETH_P_IP); 452 + if (ip_route_me_harder(net, nskb, RTN_UNSPEC)) 453 + goto free_nskb; 454 + 455 + if (nfct) { 456 + nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 457 + nf_conntrack_get(nfct); 458 + } 459 + 460 + ip_local_out(net, nskb->sk, nskb); 461 + return; 462 + 463 + free_nskb: 464 + kfree_skb(nskb); 465 + } 466 + 467 + void 468 + synproxy_send_client_synack(struct net *net, 469 + const struct sk_buff *skb, const struct tcphdr *th, 470 + const struct synproxy_options *opts) 471 + { 472 + struct sk_buff *nskb; 473 + struct iphdr *iph, *niph; 474 + struct tcphdr *nth; 475 + unsigned int tcp_hdr_size; 476 + u16 mss = opts->mss; 477 + 478 + iph = ip_hdr(skb); 479 + 480 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 481 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 482 + GFP_ATOMIC); 483 + if (!nskb) 484 + return; 485 + skb_reserve(nskb, MAX_TCP_HEADER); 486 + 487 + niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 488 + 489 + skb_reset_transport_header(nskb); 490 + nth = skb_put(nskb, tcp_hdr_size); 491 + nth->source = th->dest; 492 + nth->dest = th->source; 493 + nth->seq = htonl(__cookie_v4_init_sequence(iph, th, &mss)); 494 + nth->ack_seq = htonl(ntohl(th->seq) + 1); 495 + tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 496 + if (opts->options & NF_SYNPROXY_OPT_ECN) 497 + tcp_flag_word(nth) |= TCP_FLAG_ECE; 498 + nth->doff = tcp_hdr_size / 4; 499 + nth->window = 0; 500 + nth->check = 0; 501 + nth->urg_ptr = 0; 502 + 503 + synproxy_build_options(nth, opts); 504 + 505 + synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 506 + IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 507 + } 508 + EXPORT_SYMBOL_GPL(synproxy_send_client_synack); 509 + 510 + static void 511 + synproxy_send_server_syn(struct net *net, 512 + const struct sk_buff *skb, const struct tcphdr *th, 513 + const struct synproxy_options *opts, u32 recv_seq) 514 + { 515 + struct synproxy_net *snet = synproxy_pernet(net); 516 + struct sk_buff *nskb; 517 + struct iphdr *iph, *niph; 518 + struct tcphdr *nth; 519 + unsigned int tcp_hdr_size; 520 + 521 + iph = ip_hdr(skb); 522 + 523 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 524 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 525 + GFP_ATOMIC); 526 + if (!nskb) 527 + return; 528 + skb_reserve(nskb, MAX_TCP_HEADER); 529 + 530 + niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 531 + 532 + skb_reset_transport_header(nskb); 533 + nth = skb_put(nskb, tcp_hdr_size); 534 + nth->source = th->source; 535 + nth->dest = th->dest; 536 + nth->seq = htonl(recv_seq - 1); 537 + /* ack_seq is used to relay our ISN to the synproxy hook to initialize 538 + * sequence number translation once a connection tracking entry exists. 539 + */ 540 + nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 541 + tcp_flag_word(nth) = TCP_FLAG_SYN; 542 + if (opts->options & NF_SYNPROXY_OPT_ECN) 543 + tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 544 + nth->doff = tcp_hdr_size / 4; 545 + nth->window = th->window; 546 + nth->check = 0; 547 + nth->urg_ptr = 0; 548 + 549 + synproxy_build_options(nth, opts); 550 + 551 + synproxy_send_tcp(net, skb, nskb, &snet->tmpl->ct_general, IP_CT_NEW, 552 + niph, nth, tcp_hdr_size); 553 + } 554 + 555 + static void 556 + synproxy_send_server_ack(struct net *net, 557 + const struct ip_ct_tcp *state, 558 + const struct sk_buff *skb, const struct tcphdr *th, 559 + const struct synproxy_options *opts) 560 + { 561 + struct sk_buff *nskb; 562 + struct iphdr *iph, *niph; 563 + struct tcphdr *nth; 564 + unsigned int tcp_hdr_size; 565 + 566 + iph = ip_hdr(skb); 567 + 568 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 569 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 570 + GFP_ATOMIC); 571 + if (!nskb) 572 + return; 573 + skb_reserve(nskb, MAX_TCP_HEADER); 574 + 575 + niph = synproxy_build_ip(net, nskb, iph->daddr, iph->saddr); 576 + 577 + skb_reset_transport_header(nskb); 578 + nth = skb_put(nskb, tcp_hdr_size); 579 + nth->source = th->dest; 580 + nth->dest = th->source; 581 + nth->seq = htonl(ntohl(th->ack_seq)); 582 + nth->ack_seq = htonl(ntohl(th->seq) + 1); 583 + tcp_flag_word(nth) = TCP_FLAG_ACK; 584 + nth->doff = tcp_hdr_size / 4; 585 + nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 586 + nth->check = 0; 587 + nth->urg_ptr = 0; 588 + 589 + synproxy_build_options(nth, opts); 590 + 591 + synproxy_send_tcp(net, skb, nskb, NULL, 0, niph, nth, tcp_hdr_size); 592 + } 593 + 594 + static void 595 + synproxy_send_client_ack(struct net *net, 596 + const struct sk_buff *skb, const struct tcphdr *th, 597 + const struct synproxy_options *opts) 598 + { 599 + struct sk_buff *nskb; 600 + struct iphdr *iph, *niph; 601 + struct tcphdr *nth; 602 + unsigned int tcp_hdr_size; 603 + 604 + iph = ip_hdr(skb); 605 + 606 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 607 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 608 + GFP_ATOMIC); 609 + if (!nskb) 610 + return; 611 + skb_reserve(nskb, MAX_TCP_HEADER); 612 + 613 + niph = synproxy_build_ip(net, nskb, iph->saddr, iph->daddr); 614 + 615 + skb_reset_transport_header(nskb); 616 + nth = skb_put(nskb, tcp_hdr_size); 617 + nth->source = th->source; 618 + nth->dest = th->dest; 619 + nth->seq = htonl(ntohl(th->seq) + 1); 620 + nth->ack_seq = th->ack_seq; 621 + tcp_flag_word(nth) = TCP_FLAG_ACK; 622 + nth->doff = tcp_hdr_size / 4; 623 + nth->window = htons(ntohs(th->window) >> opts->wscale); 624 + nth->check = 0; 625 + nth->urg_ptr = 0; 626 + 627 + synproxy_build_options(nth, opts); 628 + 629 + synproxy_send_tcp(net, skb, nskb, skb_nfct(skb), 630 + IP_CT_ESTABLISHED_REPLY, niph, nth, tcp_hdr_size); 631 + } 632 + 633 + bool 634 + synproxy_recv_client_ack(struct net *net, 635 + const struct sk_buff *skb, const struct tcphdr *th, 636 + struct synproxy_options *opts, u32 recv_seq) 637 + { 638 + struct synproxy_net *snet = synproxy_pernet(net); 639 + int mss; 640 + 641 + mss = __cookie_v4_check(ip_hdr(skb), th, ntohl(th->ack_seq) - 1); 642 + if (mss == 0) { 643 + this_cpu_inc(snet->stats->cookie_invalid); 644 + return false; 645 + } 646 + 647 + this_cpu_inc(snet->stats->cookie_valid); 648 + opts->mss = mss; 649 + opts->options |= NF_SYNPROXY_OPT_MSS; 650 + 651 + if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 652 + synproxy_check_timestamp_cookie(opts); 653 + 654 + synproxy_send_server_syn(net, skb, th, opts, recv_seq); 655 + return true; 656 + } 657 + EXPORT_SYMBOL_GPL(synproxy_recv_client_ack); 658 + 659 + unsigned int 660 + ipv4_synproxy_hook(void *priv, struct sk_buff *skb, 661 + const struct nf_hook_state *nhs) 662 + { 663 + struct net *net = nhs->net; 664 + struct synproxy_net *snet = synproxy_pernet(net); 665 + enum ip_conntrack_info ctinfo; 666 + struct nf_conn *ct; 667 + struct nf_conn_synproxy *synproxy; 668 + struct synproxy_options opts = {}; 669 + const struct ip_ct_tcp *state; 670 + struct tcphdr *th, _th; 671 + unsigned int thoff; 672 + 673 + ct = nf_ct_get(skb, &ctinfo); 674 + if (!ct) 675 + return NF_ACCEPT; 676 + 677 + synproxy = nfct_synproxy(ct); 678 + if (!synproxy) 679 + return NF_ACCEPT; 680 + 681 + if (nf_is_loopback_packet(skb) || 682 + ip_hdr(skb)->protocol != IPPROTO_TCP) 683 + return NF_ACCEPT; 684 + 685 + thoff = ip_hdrlen(skb); 686 + th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 687 + if (!th) 688 + return NF_DROP; 689 + 690 + state = &ct->proto.tcp; 691 + switch (state->state) { 692 + case TCP_CONNTRACK_CLOSE: 693 + if (th->rst && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 694 + nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 695 + ntohl(th->seq) + 1); 696 + break; 697 + } 698 + 699 + if (!th->syn || th->ack || 700 + CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 701 + break; 702 + 703 + /* Reopened connection - reset the sequence number and timestamp 704 + * adjustments, they will get initialized once the connection is 705 + * reestablished. 706 + */ 707 + nf_ct_seqadj_init(ct, ctinfo, 0); 708 + synproxy->tsoff = 0; 709 + this_cpu_inc(snet->stats->conn_reopened); 710 + 711 + /* fall through */ 712 + case TCP_CONNTRACK_SYN_SENT: 713 + if (!synproxy_parse_options(skb, thoff, th, &opts)) 714 + return NF_DROP; 715 + 716 + if (!th->syn && th->ack && 717 + CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 718 + /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 719 + * therefore we need to add 1 to make the SYN sequence 720 + * number match the one of first SYN. 721 + */ 722 + if (synproxy_recv_client_ack(net, skb, th, &opts, 723 + ntohl(th->seq) + 1)) { 724 + this_cpu_inc(snet->stats->cookie_retrans); 725 + consume_skb(skb); 726 + return NF_STOLEN; 727 + } else { 728 + return NF_DROP; 729 + } 730 + } 731 + 732 + synproxy->isn = ntohl(th->ack_seq); 733 + if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) 734 + synproxy->its = opts.tsecr; 735 + 736 + nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 737 + break; 738 + case TCP_CONNTRACK_SYN_RECV: 739 + if (!th->syn || !th->ack) 740 + break; 741 + 742 + if (!synproxy_parse_options(skb, thoff, th, &opts)) 743 + return NF_DROP; 744 + 745 + if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) { 746 + synproxy->tsoff = opts.tsval - synproxy->its; 747 + nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 748 + } 749 + 750 + opts.options &= ~(NF_SYNPROXY_OPT_MSS | 751 + NF_SYNPROXY_OPT_WSCALE | 752 + NF_SYNPROXY_OPT_SACK_PERM); 753 + 754 + swap(opts.tsval, opts.tsecr); 755 + synproxy_send_server_ack(net, state, skb, th, &opts); 756 + 757 + nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 758 + nf_conntrack_event_cache(IPCT_SEQADJ, ct); 759 + 760 + swap(opts.tsval, opts.tsecr); 761 + synproxy_send_client_ack(net, skb, th, &opts); 762 + 763 + consume_skb(skb); 764 + return NF_STOLEN; 765 + default: 766 + break; 767 + } 768 + 769 + synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 770 + return NF_ACCEPT; 771 + } 772 + EXPORT_SYMBOL_GPL(ipv4_synproxy_hook); 773 + 774 + static const struct nf_hook_ops ipv4_synproxy_ops[] = { 775 + { 776 + .hook = ipv4_synproxy_hook, 777 + .pf = NFPROTO_IPV4, 778 + .hooknum = NF_INET_LOCAL_IN, 779 + .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 780 + }, 781 + { 782 + .hook = ipv4_synproxy_hook, 783 + .pf = NFPROTO_IPV4, 784 + .hooknum = NF_INET_POST_ROUTING, 785 + .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 786 + }, 787 + }; 788 + 789 + int nf_synproxy_ipv4_init(struct synproxy_net *snet, struct net *net) 790 + { 791 + int err; 792 + 793 + if (snet->hook_ref4 == 0) { 794 + err = nf_register_net_hooks(net, ipv4_synproxy_ops, 795 + ARRAY_SIZE(ipv4_synproxy_ops)); 796 + if (err) 797 + return err; 798 + } 799 + 800 + snet->hook_ref4++; 801 + return 0; 802 + } 803 + EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_init); 804 + 805 + void nf_synproxy_ipv4_fini(struct synproxy_net *snet, struct net *net) 806 + { 807 + snet->hook_ref4--; 808 + if (snet->hook_ref4 == 0) 809 + nf_unregister_net_hooks(net, ipv4_synproxy_ops, 810 + ARRAY_SIZE(ipv4_synproxy_ops)); 811 + } 812 + EXPORT_SYMBOL_GPL(nf_synproxy_ipv4_fini); 813 + 814 + #if IS_ENABLED(CONFIG_IPV6) 815 + static struct ipv6hdr * 816 + synproxy_build_ip_ipv6(struct net *net, struct sk_buff *skb, 817 + const struct in6_addr *saddr, 818 + const struct in6_addr *daddr) 819 + { 820 + struct ipv6hdr *iph; 821 + 822 + skb_reset_network_header(skb); 823 + iph = skb_put(skb, sizeof(*iph)); 824 + ip6_flow_hdr(iph, 0, 0); 825 + iph->hop_limit = net->ipv6.devconf_all->hop_limit; 826 + iph->nexthdr = IPPROTO_TCP; 827 + iph->saddr = *saddr; 828 + iph->daddr = *daddr; 829 + 830 + return iph; 831 + } 832 + 833 + static void 834 + synproxy_send_tcp_ipv6(struct net *net, 835 + const struct sk_buff *skb, struct sk_buff *nskb, 836 + struct nf_conntrack *nfct, enum ip_conntrack_info ctinfo, 837 + struct ipv6hdr *niph, struct tcphdr *nth, 838 + unsigned int tcp_hdr_size) 839 + { 840 + struct dst_entry *dst; 841 + struct flowi6 fl6; 842 + int err; 843 + 844 + nth->check = ~tcp_v6_check(tcp_hdr_size, &niph->saddr, &niph->daddr, 0); 845 + nskb->ip_summed = CHECKSUM_PARTIAL; 846 + nskb->csum_start = (unsigned char *)nth - nskb->head; 847 + nskb->csum_offset = offsetof(struct tcphdr, check); 848 + 849 + memset(&fl6, 0, sizeof(fl6)); 850 + fl6.flowi6_proto = IPPROTO_TCP; 851 + fl6.saddr = niph->saddr; 852 + fl6.daddr = niph->daddr; 853 + fl6.fl6_sport = nth->source; 854 + fl6.fl6_dport = nth->dest; 855 + security_skb_classify_flow((struct sk_buff *)skb, 856 + flowi6_to_flowi(&fl6)); 857 + err = nf_ip6_route(net, &dst, flowi6_to_flowi(&fl6), false); 858 + if (err) { 859 + goto free_nskb; 860 + } 861 + 862 + dst = xfrm_lookup(net, dst, flowi6_to_flowi(&fl6), NULL, 0); 863 + if (IS_ERR(dst)) 864 + goto free_nskb; 865 + 866 + skb_dst_set(nskb, dst); 867 + 868 + if (nfct) { 869 + nf_ct_set(nskb, (struct nf_conn *)nfct, ctinfo); 870 + nf_conntrack_get(nfct); 871 + } 872 + 873 + ip6_local_out(net, nskb->sk, nskb); 874 + return; 875 + 876 + free_nskb: 877 + kfree_skb(nskb); 878 + } 879 + 880 + void 881 + synproxy_send_client_synack_ipv6(struct net *net, 882 + const struct sk_buff *skb, 883 + const struct tcphdr *th, 884 + const struct synproxy_options *opts) 885 + { 886 + struct sk_buff *nskb; 887 + struct ipv6hdr *iph, *niph; 888 + struct tcphdr *nth; 889 + unsigned int tcp_hdr_size; 890 + u16 mss = opts->mss; 891 + 892 + iph = ipv6_hdr(skb); 893 + 894 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 895 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 896 + GFP_ATOMIC); 897 + if (!nskb) 898 + return; 899 + skb_reserve(nskb, MAX_TCP_HEADER); 900 + 901 + niph = synproxy_build_ip_ipv6(net, nskb, &iph->daddr, &iph->saddr); 902 + 903 + skb_reset_transport_header(nskb); 904 + nth = skb_put(nskb, tcp_hdr_size); 905 + nth->source = th->dest; 906 + nth->dest = th->source; 907 + nth->seq = htonl(nf_ipv6_cookie_init_sequence(iph, th, &mss)); 908 + nth->ack_seq = htonl(ntohl(th->seq) + 1); 909 + tcp_flag_word(nth) = TCP_FLAG_SYN | TCP_FLAG_ACK; 910 + if (opts->options & NF_SYNPROXY_OPT_ECN) 911 + tcp_flag_word(nth) |= TCP_FLAG_ECE; 912 + nth->doff = tcp_hdr_size / 4; 913 + nth->window = 0; 914 + nth->check = 0; 915 + nth->urg_ptr = 0; 916 + 917 + synproxy_build_options(nth, opts); 918 + 919 + synproxy_send_tcp_ipv6(net, skb, nskb, skb_nfct(skb), 920 + IP_CT_ESTABLISHED_REPLY, niph, nth, 921 + tcp_hdr_size); 922 + } 923 + EXPORT_SYMBOL_GPL(synproxy_send_client_synack_ipv6); 924 + 925 + static void 926 + synproxy_send_server_syn_ipv6(struct net *net, const struct sk_buff *skb, 927 + const struct tcphdr *th, 928 + const struct synproxy_options *opts, u32 recv_seq) 929 + { 930 + struct synproxy_net *snet = synproxy_pernet(net); 931 + struct sk_buff *nskb; 932 + struct ipv6hdr *iph, *niph; 933 + struct tcphdr *nth; 934 + unsigned int tcp_hdr_size; 935 + 936 + iph = ipv6_hdr(skb); 937 + 938 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 939 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 940 + GFP_ATOMIC); 941 + if (!nskb) 942 + return; 943 + skb_reserve(nskb, MAX_TCP_HEADER); 944 + 945 + niph = synproxy_build_ip_ipv6(net, nskb, &iph->saddr, &iph->daddr); 946 + 947 + skb_reset_transport_header(nskb); 948 + nth = skb_put(nskb, tcp_hdr_size); 949 + nth->source = th->source; 950 + nth->dest = th->dest; 951 + nth->seq = htonl(recv_seq - 1); 952 + /* ack_seq is used to relay our ISN to the synproxy hook to initialize 953 + * sequence number translation once a connection tracking entry exists. 954 + */ 955 + nth->ack_seq = htonl(ntohl(th->ack_seq) - 1); 956 + tcp_flag_word(nth) = TCP_FLAG_SYN; 957 + if (opts->options & NF_SYNPROXY_OPT_ECN) 958 + tcp_flag_word(nth) |= TCP_FLAG_ECE | TCP_FLAG_CWR; 959 + nth->doff = tcp_hdr_size / 4; 960 + nth->window = th->window; 961 + nth->check = 0; 962 + nth->urg_ptr = 0; 963 + 964 + synproxy_build_options(nth, opts); 965 + 966 + synproxy_send_tcp_ipv6(net, skb, nskb, &snet->tmpl->ct_general, 967 + IP_CT_NEW, niph, nth, tcp_hdr_size); 968 + } 969 + 970 + static void 971 + synproxy_send_server_ack_ipv6(struct net *net, const struct ip_ct_tcp *state, 972 + const struct sk_buff *skb, 973 + const struct tcphdr *th, 974 + const struct synproxy_options *opts) 975 + { 976 + struct sk_buff *nskb; 977 + struct ipv6hdr *iph, *niph; 978 + struct tcphdr *nth; 979 + unsigned int tcp_hdr_size; 980 + 981 + iph = ipv6_hdr(skb); 982 + 983 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 984 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 985 + GFP_ATOMIC); 986 + if (!nskb) 987 + return; 988 + skb_reserve(nskb, MAX_TCP_HEADER); 989 + 990 + niph = synproxy_build_ip_ipv6(net, nskb, &iph->daddr, &iph->saddr); 991 + 992 + skb_reset_transport_header(nskb); 993 + nth = skb_put(nskb, tcp_hdr_size); 994 + nth->source = th->dest; 995 + nth->dest = th->source; 996 + nth->seq = htonl(ntohl(th->ack_seq)); 997 + nth->ack_seq = htonl(ntohl(th->seq) + 1); 998 + tcp_flag_word(nth) = TCP_FLAG_ACK; 999 + nth->doff = tcp_hdr_size / 4; 1000 + nth->window = htons(state->seen[IP_CT_DIR_ORIGINAL].td_maxwin); 1001 + nth->check = 0; 1002 + nth->urg_ptr = 0; 1003 + 1004 + synproxy_build_options(nth, opts); 1005 + 1006 + synproxy_send_tcp_ipv6(net, skb, nskb, NULL, 0, niph, nth, 1007 + tcp_hdr_size); 1008 + } 1009 + 1010 + static void 1011 + synproxy_send_client_ack_ipv6(struct net *net, const struct sk_buff *skb, 1012 + const struct tcphdr *th, 1013 + const struct synproxy_options *opts) 1014 + { 1015 + struct sk_buff *nskb; 1016 + struct ipv6hdr *iph, *niph; 1017 + struct tcphdr *nth; 1018 + unsigned int tcp_hdr_size; 1019 + 1020 + iph = ipv6_hdr(skb); 1021 + 1022 + tcp_hdr_size = sizeof(*nth) + synproxy_options_size(opts); 1023 + nskb = alloc_skb(sizeof(*niph) + tcp_hdr_size + MAX_TCP_HEADER, 1024 + GFP_ATOMIC); 1025 + if (!nskb) 1026 + return; 1027 + skb_reserve(nskb, MAX_TCP_HEADER); 1028 + 1029 + niph = synproxy_build_ip_ipv6(net, nskb, &iph->saddr, &iph->daddr); 1030 + 1031 + skb_reset_transport_header(nskb); 1032 + nth = skb_put(nskb, tcp_hdr_size); 1033 + nth->source = th->source; 1034 + nth->dest = th->dest; 1035 + nth->seq = htonl(ntohl(th->seq) + 1); 1036 + nth->ack_seq = th->ack_seq; 1037 + tcp_flag_word(nth) = TCP_FLAG_ACK; 1038 + nth->doff = tcp_hdr_size / 4; 1039 + nth->window = htons(ntohs(th->window) >> opts->wscale); 1040 + nth->check = 0; 1041 + nth->urg_ptr = 0; 1042 + 1043 + synproxy_build_options(nth, opts); 1044 + 1045 + synproxy_send_tcp_ipv6(net, skb, nskb, skb_nfct(skb), 1046 + IP_CT_ESTABLISHED_REPLY, niph, nth, 1047 + tcp_hdr_size); 1048 + } 1049 + 1050 + bool 1051 + synproxy_recv_client_ack_ipv6(struct net *net, 1052 + const struct sk_buff *skb, 1053 + const struct tcphdr *th, 1054 + struct synproxy_options *opts, u32 recv_seq) 1055 + { 1056 + struct synproxy_net *snet = synproxy_pernet(net); 1057 + int mss; 1058 + 1059 + mss = nf_cookie_v6_check(ipv6_hdr(skb), th, ntohl(th->ack_seq) - 1); 1060 + if (mss == 0) { 1061 + this_cpu_inc(snet->stats->cookie_invalid); 1062 + return false; 1063 + } 1064 + 1065 + this_cpu_inc(snet->stats->cookie_valid); 1066 + opts->mss = mss; 1067 + opts->options |= NF_SYNPROXY_OPT_MSS; 1068 + 1069 + if (opts->options & NF_SYNPROXY_OPT_TIMESTAMP) 1070 + synproxy_check_timestamp_cookie(opts); 1071 + 1072 + synproxy_send_server_syn_ipv6(net, skb, th, opts, recv_seq); 1073 + return true; 1074 + } 1075 + EXPORT_SYMBOL_GPL(synproxy_recv_client_ack_ipv6); 1076 + 1077 + unsigned int 1078 + ipv6_synproxy_hook(void *priv, struct sk_buff *skb, 1079 + const struct nf_hook_state *nhs) 1080 + { 1081 + struct net *net = nhs->net; 1082 + struct synproxy_net *snet = synproxy_pernet(net); 1083 + enum ip_conntrack_info ctinfo; 1084 + struct nf_conn *ct; 1085 + struct nf_conn_synproxy *synproxy; 1086 + struct synproxy_options opts = {}; 1087 + const struct ip_ct_tcp *state; 1088 + struct tcphdr *th, _th; 1089 + __be16 frag_off; 1090 + u8 nexthdr; 1091 + int thoff; 1092 + 1093 + ct = nf_ct_get(skb, &ctinfo); 1094 + if (!ct) 1095 + return NF_ACCEPT; 1096 + 1097 + synproxy = nfct_synproxy(ct); 1098 + if (!synproxy) 1099 + return NF_ACCEPT; 1100 + 1101 + if (nf_is_loopback_packet(skb)) 1102 + return NF_ACCEPT; 1103 + 1104 + nexthdr = ipv6_hdr(skb)->nexthdr; 1105 + thoff = ipv6_skip_exthdr(skb, sizeof(struct ipv6hdr), &nexthdr, 1106 + &frag_off); 1107 + if (thoff < 0 || nexthdr != IPPROTO_TCP) 1108 + return NF_ACCEPT; 1109 + 1110 + th = skb_header_pointer(skb, thoff, sizeof(_th), &_th); 1111 + if (!th) 1112 + return NF_DROP; 1113 + 1114 + state = &ct->proto.tcp; 1115 + switch (state->state) { 1116 + case TCP_CONNTRACK_CLOSE: 1117 + if (th->rst && !test_bit(IPS_SEEN_REPLY_BIT, &ct->status)) { 1118 + nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - 1119 + ntohl(th->seq) + 1); 1120 + break; 1121 + } 1122 + 1123 + if (!th->syn || th->ack || 1124 + CTINFO2DIR(ctinfo) != IP_CT_DIR_ORIGINAL) 1125 + break; 1126 + 1127 + /* Reopened connection - reset the sequence number and timestamp 1128 + * adjustments, they will get initialized once the connection is 1129 + * reestablished. 1130 + */ 1131 + nf_ct_seqadj_init(ct, ctinfo, 0); 1132 + synproxy->tsoff = 0; 1133 + this_cpu_inc(snet->stats->conn_reopened); 1134 + 1135 + /* fall through */ 1136 + case TCP_CONNTRACK_SYN_SENT: 1137 + if (!synproxy_parse_options(skb, thoff, th, &opts)) 1138 + return NF_DROP; 1139 + 1140 + if (!th->syn && th->ack && 1141 + CTINFO2DIR(ctinfo) == IP_CT_DIR_ORIGINAL) { 1142 + /* Keep-Alives are sent with SEG.SEQ = SND.NXT-1, 1143 + * therefore we need to add 1 to make the SYN sequence 1144 + * number match the one of first SYN. 1145 + */ 1146 + if (synproxy_recv_client_ack_ipv6(net, skb, th, &opts, 1147 + ntohl(th->seq) + 1)) { 1148 + this_cpu_inc(snet->stats->cookie_retrans); 1149 + consume_skb(skb); 1150 + return NF_STOLEN; 1151 + } else { 1152 + return NF_DROP; 1153 + } 1154 + } 1155 + 1156 + synproxy->isn = ntohl(th->ack_seq); 1157 + if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) 1158 + synproxy->its = opts.tsecr; 1159 + 1160 + nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 1161 + break; 1162 + case TCP_CONNTRACK_SYN_RECV: 1163 + if (!th->syn || !th->ack) 1164 + break; 1165 + 1166 + if (!synproxy_parse_options(skb, thoff, th, &opts)) 1167 + return NF_DROP; 1168 + 1169 + if (opts.options & NF_SYNPROXY_OPT_TIMESTAMP) { 1170 + synproxy->tsoff = opts.tsval - synproxy->its; 1171 + nf_conntrack_event_cache(IPCT_SYNPROXY, ct); 1172 + } 1173 + 1174 + opts.options &= ~(NF_SYNPROXY_OPT_MSS | 1175 + NF_SYNPROXY_OPT_WSCALE | 1176 + NF_SYNPROXY_OPT_SACK_PERM); 1177 + 1178 + swap(opts.tsval, opts.tsecr); 1179 + synproxy_send_server_ack_ipv6(net, state, skb, th, &opts); 1180 + 1181 + nf_ct_seqadj_init(ct, ctinfo, synproxy->isn - ntohl(th->seq)); 1182 + nf_conntrack_event_cache(IPCT_SEQADJ, ct); 1183 + 1184 + swap(opts.tsval, opts.tsecr); 1185 + synproxy_send_client_ack_ipv6(net, skb, th, &opts); 1186 + 1187 + consume_skb(skb); 1188 + return NF_STOLEN; 1189 + default: 1190 + break; 1191 + } 1192 + 1193 + synproxy_tstamp_adjust(skb, thoff, th, ct, ctinfo, synproxy); 1194 + return NF_ACCEPT; 1195 + } 1196 + EXPORT_SYMBOL_GPL(ipv6_synproxy_hook); 1197 + 1198 + static const struct nf_hook_ops ipv6_synproxy_ops[] = { 1199 + { 1200 + .hook = ipv6_synproxy_hook, 1201 + .pf = NFPROTO_IPV6, 1202 + .hooknum = NF_INET_LOCAL_IN, 1203 + .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 1204 + }, 1205 + { 1206 + .hook = ipv6_synproxy_hook, 1207 + .pf = NFPROTO_IPV6, 1208 + .hooknum = NF_INET_POST_ROUTING, 1209 + .priority = NF_IP_PRI_CONNTRACK_CONFIRM - 1, 1210 + }, 1211 + }; 1212 + 1213 + int 1214 + nf_synproxy_ipv6_init(struct synproxy_net *snet, struct net *net) 1215 + { 1216 + int err; 1217 + 1218 + if (snet->hook_ref6 == 0) { 1219 + err = nf_register_net_hooks(net, ipv6_synproxy_ops, 1220 + ARRAY_SIZE(ipv6_synproxy_ops)); 1221 + if (err) 1222 + return err; 1223 + } 1224 + 1225 + snet->hook_ref6++; 1226 + return 0; 1227 + } 1228 + EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_init); 1229 + 1230 + void 1231 + nf_synproxy_ipv6_fini(struct synproxy_net *snet, struct net *net) 1232 + { 1233 + snet->hook_ref6--; 1234 + if (snet->hook_ref6 == 0) 1235 + nf_unregister_net_hooks(net, ipv6_synproxy_ops, 1236 + ARRAY_SIZE(ipv6_synproxy_ops)); 1237 + } 1238 + EXPORT_SYMBOL_GPL(nf_synproxy_ipv6_fini); 1239 + #endif /* CONFIG_IPV6 */ 412 1240 413 1241 MODULE_LICENSE("GPL"); 414 1242 MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+20 -6
net/netfilter/nf_tables_api.c
··· 3870 3870 [NFTA_SET_ELEM_DATA] = { .type = NLA_NESTED }, 3871 3871 [NFTA_SET_ELEM_FLAGS] = { .type = NLA_U32 }, 3872 3872 [NFTA_SET_ELEM_TIMEOUT] = { .type = NLA_U64 }, 3873 + [NFTA_SET_ELEM_EXPIRATION] = { .type = NLA_U64 }, 3873 3874 [NFTA_SET_ELEM_USERDATA] = { .type = NLA_BINARY, 3874 3875 .len = NFT_USERDATA_MAXLEN }, 3875 3876 [NFTA_SET_ELEM_EXPR] = { .type = NLA_NESTED }, ··· 4324 4323 void *nft_set_elem_init(const struct nft_set *set, 4325 4324 const struct nft_set_ext_tmpl *tmpl, 4326 4325 const u32 *key, const u32 *data, 4327 - u64 timeout, gfp_t gfp) 4326 + u64 timeout, u64 expiration, gfp_t gfp) 4328 4327 { 4329 4328 struct nft_set_ext *ext; 4330 4329 void *elem; ··· 4339 4338 memcpy(nft_set_ext_key(ext), key, set->klen); 4340 4339 if (nft_set_ext_exists(ext, NFT_SET_EXT_DATA)) 4341 4340 memcpy(nft_set_ext_data(ext), data, set->dlen); 4342 - if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) 4343 - *nft_set_ext_expiration(ext) = 4344 - get_jiffies_64() + timeout; 4341 + if (nft_set_ext_exists(ext, NFT_SET_EXT_EXPIRATION)) { 4342 + *nft_set_ext_expiration(ext) = get_jiffies_64() + expiration; 4343 + if (expiration == 0) 4344 + *nft_set_ext_expiration(ext) += timeout; 4345 + } 4345 4346 if (nft_set_ext_exists(ext, NFT_SET_EXT_TIMEOUT)) 4346 4347 *nft_set_ext_timeout(ext) = timeout; 4347 4348 ··· 4408 4405 struct nft_trans *trans; 4409 4406 u32 flags = 0; 4410 4407 u64 timeout; 4408 + u64 expiration; 4411 4409 u8 ulen; 4412 4410 int err; 4413 4411 ··· 4450 4446 return err; 4451 4447 } else if (set->flags & NFT_SET_TIMEOUT) { 4452 4448 timeout = set->timeout; 4449 + } 4450 + 4451 + expiration = 0; 4452 + if (nla[NFTA_SET_ELEM_EXPIRATION] != NULL) { 4453 + if (!(set->flags & NFT_SET_TIMEOUT)) 4454 + return -EINVAL; 4455 + err = nf_msecs_to_jiffies64(nla[NFTA_SET_ELEM_EXPIRATION], 4456 + &expiration); 4457 + if (err) 4458 + return err; 4453 4459 } 4454 4460 4455 4461 err = nft_data_init(ctx, &elem.key.val, sizeof(elem.key), &d1, ··· 4544 4530 4545 4531 err = -ENOMEM; 4546 4532 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, data.data, 4547 - timeout, GFP_KERNEL); 4533 + timeout, expiration, GFP_KERNEL); 4548 4534 if (elem.priv == NULL) 4549 4535 goto err3; 4550 4536 ··· 4746 4732 4747 4733 err = -ENOMEM; 4748 4734 elem.priv = nft_set_elem_init(set, &tmpl, elem.key.val.data, NULL, 0, 4749 - GFP_KERNEL); 4735 + 0, GFP_KERNEL); 4750 4736 if (elem.priv == NULL) 4751 4737 goto err2; 4752 4738
+140 -2
net/netfilter/nft_ct.c
··· 21 21 #include <net/netfilter/nf_conntrack_labels.h> 22 22 #include <net/netfilter/nf_conntrack_timeout.h> 23 23 #include <net/netfilter/nf_conntrack_l4proto.h> 24 + #include <net/netfilter/nf_conntrack_expect.h> 24 25 25 26 struct nft_ct { 26 27 enum nft_ct_keys key:8; ··· 1154 1153 .owner = THIS_MODULE, 1155 1154 }; 1156 1155 1156 + struct nft_ct_expect_obj { 1157 + u16 l3num; 1158 + __be16 dport; 1159 + u8 l4proto; 1160 + u8 size; 1161 + u32 timeout; 1162 + }; 1163 + 1164 + static int nft_ct_expect_obj_init(const struct nft_ctx *ctx, 1165 + const struct nlattr * const tb[], 1166 + struct nft_object *obj) 1167 + { 1168 + struct nft_ct_expect_obj *priv = nft_obj_data(obj); 1169 + 1170 + if (!tb[NFTA_CT_EXPECT_L4PROTO] || 1171 + !tb[NFTA_CT_EXPECT_DPORT] || 1172 + !tb[NFTA_CT_EXPECT_TIMEOUT] || 1173 + !tb[NFTA_CT_EXPECT_SIZE]) 1174 + return -EINVAL; 1175 + 1176 + priv->l3num = ctx->family; 1177 + if (tb[NFTA_CT_EXPECT_L3PROTO]) 1178 + priv->l3num = ntohs(nla_get_be16(tb[NFTA_CT_EXPECT_L3PROTO])); 1179 + 1180 + priv->l4proto = nla_get_u8(tb[NFTA_CT_EXPECT_L4PROTO]); 1181 + priv->dport = nla_get_be16(tb[NFTA_CT_EXPECT_DPORT]); 1182 + priv->timeout = nla_get_u32(tb[NFTA_CT_EXPECT_TIMEOUT]); 1183 + priv->size = nla_get_u8(tb[NFTA_CT_EXPECT_SIZE]); 1184 + 1185 + return nf_ct_netns_get(ctx->net, ctx->family); 1186 + } 1187 + 1188 + static void nft_ct_expect_obj_destroy(const struct nft_ctx *ctx, 1189 + struct nft_object *obj) 1190 + { 1191 + nf_ct_netns_put(ctx->net, ctx->family); 1192 + } 1193 + 1194 + static int nft_ct_expect_obj_dump(struct sk_buff *skb, 1195 + struct nft_object *obj, bool reset) 1196 + { 1197 + const struct nft_ct_expect_obj *priv = nft_obj_data(obj); 1198 + 1199 + if (nla_put_be16(skb, NFTA_CT_EXPECT_L3PROTO, htons(priv->l3num)) || 1200 + nla_put_u8(skb, NFTA_CT_EXPECT_L4PROTO, priv->l4proto) || 1201 + nla_put_be16(skb, NFTA_CT_EXPECT_DPORT, priv->dport) || 1202 + nla_put_u32(skb, NFTA_CT_EXPECT_TIMEOUT, priv->timeout) || 1203 + nla_put_u8(skb, NFTA_CT_EXPECT_SIZE, priv->size)) 1204 + return -1; 1205 + 1206 + return 0; 1207 + } 1208 + 1209 + static void nft_ct_expect_obj_eval(struct nft_object *obj, 1210 + struct nft_regs *regs, 1211 + const struct nft_pktinfo *pkt) 1212 + { 1213 + const struct nft_ct_expect_obj *priv = nft_obj_data(obj); 1214 + struct nf_conntrack_expect *exp; 1215 + enum ip_conntrack_info ctinfo; 1216 + struct nf_conn_help *help; 1217 + enum ip_conntrack_dir dir; 1218 + u16 l3num = priv->l3num; 1219 + struct nf_conn *ct; 1220 + 1221 + ct = nf_ct_get(pkt->skb, &ctinfo); 1222 + if (!ct || ctinfo == IP_CT_UNTRACKED) { 1223 + regs->verdict.code = NFT_BREAK; 1224 + return; 1225 + } 1226 + dir = CTINFO2DIR(ctinfo); 1227 + 1228 + help = nfct_help(ct); 1229 + if (!help) 1230 + help = nf_ct_helper_ext_add(ct, GFP_ATOMIC); 1231 + if (!help) { 1232 + regs->verdict.code = NF_DROP; 1233 + return; 1234 + } 1235 + 1236 + if (help->expecting[NF_CT_EXPECT_CLASS_DEFAULT] >= priv->size) { 1237 + regs->verdict.code = NFT_BREAK; 1238 + return; 1239 + } 1240 + if (l3num == NFPROTO_INET) 1241 + l3num = nf_ct_l3num(ct); 1242 + 1243 + exp = nf_ct_expect_alloc(ct); 1244 + if (exp == NULL) { 1245 + regs->verdict.code = NF_DROP; 1246 + return; 1247 + } 1248 + nf_ct_expect_init(exp, NF_CT_EXPECT_CLASS_DEFAULT, l3num, 1249 + &ct->tuplehash[!dir].tuple.src.u3, 1250 + &ct->tuplehash[!dir].tuple.dst.u3, 1251 + priv->l4proto, NULL, &priv->dport); 1252 + exp->timeout.expires = jiffies + priv->timeout * HZ; 1253 + 1254 + if (nf_ct_expect_related(exp) != 0) 1255 + regs->verdict.code = NF_DROP; 1256 + } 1257 + 1258 + static const struct nla_policy nft_ct_expect_policy[NFTA_CT_EXPECT_MAX + 1] = { 1259 + [NFTA_CT_EXPECT_L3PROTO] = { .type = NLA_U16 }, 1260 + [NFTA_CT_EXPECT_L4PROTO] = { .type = NLA_U8 }, 1261 + [NFTA_CT_EXPECT_DPORT] = { .type = NLA_U16 }, 1262 + [NFTA_CT_EXPECT_TIMEOUT] = { .type = NLA_U32 }, 1263 + [NFTA_CT_EXPECT_SIZE] = { .type = NLA_U8 }, 1264 + }; 1265 + 1266 + static struct nft_object_type nft_ct_expect_obj_type; 1267 + 1268 + static const struct nft_object_ops nft_ct_expect_obj_ops = { 1269 + .type = &nft_ct_expect_obj_type, 1270 + .size = sizeof(struct nft_ct_expect_obj), 1271 + .eval = nft_ct_expect_obj_eval, 1272 + .init = nft_ct_expect_obj_init, 1273 + .destroy = nft_ct_expect_obj_destroy, 1274 + .dump = nft_ct_expect_obj_dump, 1275 + }; 1276 + 1277 + static struct nft_object_type nft_ct_expect_obj_type __read_mostly = { 1278 + .type = NFT_OBJECT_CT_EXPECT, 1279 + .ops = &nft_ct_expect_obj_ops, 1280 + .maxattr = NFTA_CT_EXPECT_MAX, 1281 + .policy = nft_ct_expect_policy, 1282 + .owner = THIS_MODULE, 1283 + }; 1284 + 1157 1285 static int __init nft_ct_module_init(void) 1158 1286 { 1159 1287 int err; ··· 1300 1170 err = nft_register_obj(&nft_ct_helper_obj_type); 1301 1171 if (err < 0) 1302 1172 goto err2; 1173 + 1174 + err = nft_register_obj(&nft_ct_expect_obj_type); 1175 + if (err < 0) 1176 + goto err3; 1303 1177 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 1304 1178 err = nft_register_obj(&nft_ct_timeout_obj_type); 1305 1179 if (err < 0) 1306 - goto err3; 1180 + goto err4; 1307 1181 #endif 1308 1182 return 0; 1309 1183 1310 1184 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 1185 + err4: 1186 + nft_unregister_obj(&nft_ct_expect_obj_type); 1187 + #endif 1311 1188 err3: 1312 1189 nft_unregister_obj(&nft_ct_helper_obj_type); 1313 - #endif 1314 1190 err2: 1315 1191 nft_unregister_expr(&nft_notrack_type); 1316 1192 err1: ··· 1329 1193 #ifdef CONFIG_NF_CONNTRACK_TIMEOUT 1330 1194 nft_unregister_obj(&nft_ct_timeout_obj_type); 1331 1195 #endif 1196 + nft_unregister_obj(&nft_ct_expect_obj_type); 1332 1197 nft_unregister_obj(&nft_ct_helper_obj_type); 1333 1198 nft_unregister_expr(&nft_notrack_type); 1334 1199 nft_unregister_expr(&nft_ct_type); ··· 1344 1207 MODULE_ALIAS_NFT_EXPR("notrack"); 1345 1208 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_HELPER); 1346 1209 MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_TIMEOUT); 1210 + MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_CT_EXPECT);
+1 -1
net/netfilter/nft_dynset.c
··· 56 56 elem = nft_set_elem_init(set, &priv->tmpl, 57 57 &regs->data[priv->sreg_key], 58 58 &regs->data[priv->sreg_data], 59 - timeout, GFP_ATOMIC); 59 + timeout, 0, GFP_ATOMIC); 60 60 if (elem == NULL) 61 61 goto err1; 62 62
+133
net/netfilter/nft_exthdr.c
··· 59 59 regs->verdict.code = NFT_BREAK; 60 60 } 61 61 62 + /* find the offset to specified option. 63 + * 64 + * If target header is found, its offset is set in *offset and return option 65 + * number. Otherwise, return negative error. 66 + * 67 + * If the first fragment doesn't contain the End of Options it is considered 68 + * invalid. 69 + */ 70 + static int ipv4_find_option(struct net *net, struct sk_buff *skb, 71 + unsigned int *offset, int target) 72 + { 73 + unsigned char optbuf[sizeof(struct ip_options) + 40]; 74 + struct ip_options *opt = (struct ip_options *)optbuf; 75 + struct iphdr *iph, _iph; 76 + unsigned int start; 77 + bool found = false; 78 + __be32 info; 79 + int optlen; 80 + 81 + iph = skb_header_pointer(skb, 0, sizeof(_iph), &_iph); 82 + if (!iph) 83 + return -EBADMSG; 84 + start = sizeof(struct iphdr); 85 + 86 + optlen = iph->ihl * 4 - (int)sizeof(struct iphdr); 87 + if (optlen <= 0) 88 + return -ENOENT; 89 + 90 + memset(opt, 0, sizeof(struct ip_options)); 91 + /* Copy the options since __ip_options_compile() modifies 92 + * the options. 93 + */ 94 + if (skb_copy_bits(skb, start, opt->__data, optlen)) 95 + return -EBADMSG; 96 + opt->optlen = optlen; 97 + 98 + if (__ip_options_compile(net, opt, NULL, &info)) 99 + return -EBADMSG; 100 + 101 + switch (target) { 102 + case IPOPT_SSRR: 103 + case IPOPT_LSRR: 104 + if (!opt->srr) 105 + break; 106 + found = target == IPOPT_SSRR ? opt->is_strictroute : 107 + !opt->is_strictroute; 108 + if (found) 109 + *offset = opt->srr + start; 110 + break; 111 + case IPOPT_RR: 112 + if (!opt->rr) 113 + break; 114 + *offset = opt->rr + start; 115 + found = true; 116 + break; 117 + case IPOPT_RA: 118 + if (!opt->router_alert) 119 + break; 120 + *offset = opt->router_alert + start; 121 + found = true; 122 + break; 123 + default: 124 + return -EOPNOTSUPP; 125 + } 126 + return found ? target : -ENOENT; 127 + } 128 + 129 + static void nft_exthdr_ipv4_eval(const struct nft_expr *expr, 130 + struct nft_regs *regs, 131 + const struct nft_pktinfo *pkt) 132 + { 133 + struct nft_exthdr *priv = nft_expr_priv(expr); 134 + u32 *dest = &regs->data[priv->dreg]; 135 + struct sk_buff *skb = pkt->skb; 136 + unsigned int offset; 137 + int err; 138 + 139 + if (skb->protocol != htons(ETH_P_IP)) 140 + goto err; 141 + 142 + err = ipv4_find_option(nft_net(pkt), skb, &offset, priv->type); 143 + if (priv->flags & NFT_EXTHDR_F_PRESENT) { 144 + *dest = (err >= 0); 145 + return; 146 + } else if (err < 0) { 147 + goto err; 148 + } 149 + offset += priv->offset; 150 + 151 + dest[priv->len / NFT_REG32_SIZE] = 0; 152 + if (skb_copy_bits(pkt->skb, offset, dest, priv->len) < 0) 153 + goto err; 154 + return; 155 + err: 156 + regs->verdict.code = NFT_BREAK; 157 + } 158 + 62 159 static void * 63 160 nft_tcp_header_pointer(const struct nft_pktinfo *pkt, 64 161 unsigned int len, void *buffer, unsigned int *tcphdr_len) ··· 409 312 return nft_validate_register_load(priv->sreg, priv->len); 410 313 } 411 314 315 + static int nft_exthdr_ipv4_init(const struct nft_ctx *ctx, 316 + const struct nft_expr *expr, 317 + const struct nlattr * const tb[]) 318 + { 319 + struct nft_exthdr *priv = nft_expr_priv(expr); 320 + int err = nft_exthdr_init(ctx, expr, tb); 321 + 322 + if (err < 0) 323 + return err; 324 + 325 + switch (priv->type) { 326 + case IPOPT_SSRR: 327 + case IPOPT_LSRR: 328 + case IPOPT_RR: 329 + case IPOPT_RA: 330 + break; 331 + default: 332 + return -EOPNOTSUPP; 333 + } 334 + return 0; 335 + } 336 + 412 337 static int nft_exthdr_dump_common(struct sk_buff *skb, const struct nft_exthdr *priv) 413 338 { 414 339 if (nla_put_u8(skb, NFTA_EXTHDR_TYPE, priv->type)) ··· 477 358 .dump = nft_exthdr_dump, 478 359 }; 479 360 361 + static const struct nft_expr_ops nft_exthdr_ipv4_ops = { 362 + .type = &nft_exthdr_type, 363 + .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), 364 + .eval = nft_exthdr_ipv4_eval, 365 + .init = nft_exthdr_ipv4_init, 366 + .dump = nft_exthdr_dump, 367 + }; 368 + 480 369 static const struct nft_expr_ops nft_exthdr_tcp_ops = { 481 370 .type = &nft_exthdr_type, 482 371 .size = NFT_EXPR_SIZE(sizeof(struct nft_exthdr)), ··· 524 397 case NFT_EXTHDR_OP_IPV6: 525 398 if (tb[NFTA_EXTHDR_DREG]) 526 399 return &nft_exthdr_ipv6_ops; 400 + break; 401 + case NFT_EXTHDR_OP_IPV4: 402 + if (ctx->family != NFPROTO_IPV6) { 403 + if (tb[NFTA_EXTHDR_DREG]) 404 + return &nft_exthdr_ipv4_ops; 405 + } 527 406 break; 528 407 } 529 408
+2 -2
net/netfilter/xt_iprange.c
··· 2 2 /* 3 3 * xt_iprange - Netfilter module to match IP address ranges 4 4 * 5 - * (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 + * (C) 2003 Jozsef Kadlecsik <kadlec@netfilter.org> 6 6 * (C) CC Computer Consultants GmbH, 2008 7 7 */ 8 8 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt ··· 130 130 module_init(iprange_mt_init); 131 131 module_exit(iprange_mt_exit); 132 132 MODULE_LICENSE("GPL"); 133 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 133 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 134 134 MODULE_AUTHOR("Jan Engelhardt <jengelh@medozas.de>"); 135 135 MODULE_DESCRIPTION("Xtables: arbitrary IPv4 range matching"); 136 136 MODULE_ALIAS("ipt_iprange");
+3
net/netfilter/xt_owner.c
··· 22 22 struct xt_owner_match_info *info = par->matchinfo; 23 23 struct net *net = par->net; 24 24 25 + if (info->match & ~XT_OWNER_MASK) 26 + return -EINVAL; 27 + 25 28 /* Only allow the common case where the userns of the writer 26 29 * matches the userns of the network namespace. 27 30 */
+23 -22
net/netfilter/xt_set.c
··· 2 2 /* Copyright (C) 2000-2002 Joakim Axelsson <gozem@linux.nu> 3 3 * Patrick Schaaf <bof@bof.de> 4 4 * Martin Josefsson <gandalf@wlug.westbo.se> 5 - * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 + * Copyright (C) 2003-2013 Jozsef Kadlecsik <kadlec@netfilter.org> 6 6 */ 7 7 8 8 /* Kernel module which implements the set match and SET target ··· 18 18 #include <uapi/linux/netfilter/xt_set.h> 19 19 20 20 MODULE_LICENSE("GPL"); 21 - MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>"); 21 + MODULE_AUTHOR("Jozsef Kadlecsik <kadlec@netfilter.org>"); 22 22 MODULE_DESCRIPTION("Xtables: IP set match and target module"); 23 23 MODULE_ALIAS("xt_SET"); 24 24 MODULE_ALIAS("ipt_set"); ··· 436 436 { 437 437 const struct xt_set_info_target_v3 *info = par->targinfo; 438 438 ip_set_id_t index; 439 + int ret = 0; 439 440 440 441 if (info->add_set.index != IPSET_INVALID_ID) { 441 442 index = ip_set_nfnl_get_byindex(par->net, ··· 454 453 if (index == IPSET_INVALID_ID) { 455 454 pr_info_ratelimited("Cannot find del_set index %u as target\n", 456 455 info->del_set.index); 457 - if (info->add_set.index != IPSET_INVALID_ID) 458 - ip_set_nfnl_put(par->net, 459 - info->add_set.index); 460 - return -ENOENT; 456 + ret = -ENOENT; 457 + goto cleanup_add; 461 458 } 462 459 } 463 460 464 461 if (info->map_set.index != IPSET_INVALID_ID) { 465 462 if (strncmp(par->table, "mangle", 7)) { 466 463 pr_info_ratelimited("--map-set only usable from mangle table\n"); 467 - return -EINVAL; 464 + ret = -EINVAL; 465 + goto cleanup_del; 468 466 } 469 467 if (((info->flags & IPSET_FLAG_MAP_SKBPRIO) | 470 468 (info->flags & IPSET_FLAG_MAP_SKBQUEUE)) && ··· 471 471 1 << NF_INET_LOCAL_OUT | 472 472 1 << NF_INET_POST_ROUTING))) { 473 473 pr_info_ratelimited("mapping of prio or/and queue is allowed only from OUTPUT/FORWARD/POSTROUTING chains\n"); 474 - return -EINVAL; 474 + ret = -EINVAL; 475 + goto cleanup_del; 475 476 } 476 477 index = ip_set_nfnl_get_byindex(par->net, 477 478 info->map_set.index); 478 479 if (index == IPSET_INVALID_ID) { 479 480 pr_info_ratelimited("Cannot find map_set index %u as target\n", 480 481 info->map_set.index); 481 - if (info->add_set.index != IPSET_INVALID_ID) 482 - ip_set_nfnl_put(par->net, 483 - info->add_set.index); 484 - if (info->del_set.index != IPSET_INVALID_ID) 485 - ip_set_nfnl_put(par->net, 486 - info->del_set.index); 487 - return -ENOENT; 482 + ret = -ENOENT; 483 + goto cleanup_del; 488 484 } 489 485 } 490 486 ··· 488 492 info->del_set.dim > IPSET_DIM_MAX || 489 493 info->map_set.dim > IPSET_DIM_MAX) { 490 494 pr_info_ratelimited("SET target dimension over the limit!\n"); 491 - if (info->add_set.index != IPSET_INVALID_ID) 492 - ip_set_nfnl_put(par->net, info->add_set.index); 493 - if (info->del_set.index != IPSET_INVALID_ID) 494 - ip_set_nfnl_put(par->net, info->del_set.index); 495 - if (info->map_set.index != IPSET_INVALID_ID) 496 - ip_set_nfnl_put(par->net, info->map_set.index); 497 - return -ERANGE; 495 + ret = -ERANGE; 496 + goto cleanup_mark; 498 497 } 499 498 500 499 return 0; 500 + cleanup_mark: 501 + if (info->map_set.index != IPSET_INVALID_ID) 502 + ip_set_nfnl_put(par->net, info->map_set.index); 503 + cleanup_del: 504 + if (info->del_set.index != IPSET_INVALID_ID) 505 + ip_set_nfnl_put(par->net, info->del_set.index); 506 + cleanup_add: 507 + if (info->add_set.index != IPSET_INVALID_ID) 508 + ip_set_nfnl_put(par->net, info->add_set.index); 509 + return ret; 501 510 } 502 511 503 512 static void