提交 90b2621f 编写于 作者: D David S. Miller

Merge branch 'master' of git://1984.lsi.us.es/nf

Pablo Neira Ayuso says:

====================
The following patchset contains 7 Netfilter/IPVS fixes for 3.9-rc, they are:

* Restrict IPv6 stateless NPT targets to the mangle table. Many users are
  complaining that this target does not work in the nat table, which is the
  wrong table for it, from Florian Westphal.

* Fix possible use before initialization in the netns init path of several
  conntrack protocol trackers (introduced recently while improving conntrack
  netns support), from Gao Feng.

* Fix incorrect initialization of copy_range in nfnetlink_queue, spotted
  by Eric Dumazet during the NFWS2013, patch from myself.

* Fix wrong calculation of next SCTP chunk in IPVS, from Julian Anastasov.

* Remove rcu_read_lock section in IPVS while calling ipv4_update_pmtu
  not required anymore after change introduced in 3.7, again from Julian.

* Fix SYN looping in IPVS state sync if the backup is used a real server
  in DR/TUN modes, this required a new /proc entry to disable the director
  function when acting as backup, also from Julian.

* Remove leftover IP_NF_QUEUE Kconfig after ip_queue removal, noted by
  Paul Bolle.
====================
Signed-off-by: NDavid S. Miller <davem@davemloft.net>
...@@ -15,6 +15,13 @@ amemthresh - INTEGER ...@@ -15,6 +15,13 @@ amemthresh - INTEGER
enabled and the variable is automatically set to 2, otherwise enabled and the variable is automatically set to 2, otherwise
the strategy is disabled and the variable is set to 1. the strategy is disabled and the variable is set to 1.
backup_only - BOOLEAN
0 - disabled (default)
not 0 - enabled
If set, disable the director function while the server is
in backup mode to avoid packet loops for DR/TUN methods.
conntrack - BOOLEAN conntrack - BOOLEAN
0 - disabled (default) 0 - disabled (default)
not 0 - enabled not 0 - enabled
......
...@@ -976,6 +976,7 @@ struct netns_ipvs { ...@@ -976,6 +976,7 @@ struct netns_ipvs {
int sysctl_sync_retries; int sysctl_sync_retries;
int sysctl_nat_icmp_send; int sysctl_nat_icmp_send;
int sysctl_pmtu_disc; int sysctl_pmtu_disc;
int sysctl_backup_only;
/* ip_vs_lblc */ /* ip_vs_lblc */
int sysctl_lblc_expiration; int sysctl_lblc_expiration;
...@@ -1067,6 +1068,12 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs) ...@@ -1067,6 +1068,12 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
return ipvs->sysctl_pmtu_disc; return ipvs->sysctl_pmtu_disc;
} }
static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
{
return ipvs->sync_state & IP_VS_STATE_BACKUP &&
ipvs->sysctl_backup_only;
}
#else #else
static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
...@@ -1114,6 +1121,11 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs) ...@@ -1114,6 +1121,11 @@ static inline int sysctl_pmtu_disc(struct netns_ipvs *ipvs)
return 1; return 1;
} }
static inline int sysctl_backup_only(struct netns_ipvs *ipvs)
{
return 0;
}
#endif #endif
/* /*
......
...@@ -36,19 +36,6 @@ config NF_CONNTRACK_PROC_COMPAT ...@@ -36,19 +36,6 @@ config NF_CONNTRACK_PROC_COMPAT
If unsure, say Y. If unsure, say Y.
config IP_NF_QUEUE
tristate "IP Userspace queueing via NETLINK (OBSOLETE)"
depends on NETFILTER_ADVANCED
help
Netfilter has the ability to queue packets to user space: the
netlink device can be used to access them using this driver.
This option enables the old IPv4-only "ip_queue" implementation
which has been obsoleted by the new "nfnetlink_queue" code (see
CONFIG_NETFILTER_NETLINK_QUEUE).
To compile it as a module, choose M here. If unsure, say N.
config IP_NF_IPTABLES config IP_NF_IPTABLES
tristate "IP tables support (required for filtering/masq/NAT)" tristate "IP tables support (required for filtering/masq/NAT)"
default m if NETFILTER_ADVANCED=n default m if NETFILTER_ADVANCED=n
......
...@@ -114,6 +114,7 @@ ip6t_dnpt_tg(struct sk_buff *skb, const struct xt_action_param *par) ...@@ -114,6 +114,7 @@ ip6t_dnpt_tg(struct sk_buff *skb, const struct xt_action_param *par)
static struct xt_target ip6t_npt_target_reg[] __read_mostly = { static struct xt_target ip6t_npt_target_reg[] __read_mostly = {
{ {
.name = "SNPT", .name = "SNPT",
.table = "mangle",
.target = ip6t_snpt_tg, .target = ip6t_snpt_tg,
.targetsize = sizeof(struct ip6t_npt_tginfo), .targetsize = sizeof(struct ip6t_npt_tginfo),
.checkentry = ip6t_npt_checkentry, .checkentry = ip6t_npt_checkentry,
...@@ -124,6 +125,7 @@ static struct xt_target ip6t_npt_target_reg[] __read_mostly = { ...@@ -124,6 +125,7 @@ static struct xt_target ip6t_npt_target_reg[] __read_mostly = {
}, },
{ {
.name = "DNPT", .name = "DNPT",
.table = "mangle",
.target = ip6t_dnpt_tg, .target = ip6t_dnpt_tg,
.targetsize = sizeof(struct ip6t_npt_tginfo), .targetsize = sizeof(struct ip6t_npt_tginfo),
.checkentry = ip6t_npt_checkentry, .checkentry = ip6t_npt_checkentry,
......
...@@ -1394,10 +1394,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum) ...@@ -1394,10 +1394,8 @@ ip_vs_in_icmp(struct sk_buff *skb, int *related, unsigned int hooknum)
skb_reset_network_header(skb); skb_reset_network_header(skb);
IP_VS_DBG(12, "ICMP for IPIP %pI4->%pI4: mtu=%u\n", IP_VS_DBG(12, "ICMP for IPIP %pI4->%pI4: mtu=%u\n",
&ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, mtu); &ip_hdr(skb)->saddr, &ip_hdr(skb)->daddr, mtu);
rcu_read_lock();
ipv4_update_pmtu(skb, dev_net(skb->dev), ipv4_update_pmtu(skb, dev_net(skb->dev),
mtu, 0, 0, 0, 0); mtu, 0, 0, 0, 0);
rcu_read_unlock();
/* Client uses PMTUD? */ /* Client uses PMTUD? */
if (!(cih->frag_off & htons(IP_DF))) if (!(cih->frag_off & htons(IP_DF)))
goto ignore_ipip; goto ignore_ipip;
...@@ -1577,7 +1575,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1577,7 +1575,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
} }
/* ipvs enabled in this netns ? */ /* ipvs enabled in this netns ? */
net = skb_net(skb); net = skb_net(skb);
if (!net_ipvs(net)->enable) ipvs = net_ipvs(net);
if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
return NF_ACCEPT; return NF_ACCEPT;
ip_vs_fill_iph_skb(af, skb, &iph); ip_vs_fill_iph_skb(af, skb, &iph);
...@@ -1654,7 +1653,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1654,7 +1653,6 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
} }
IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet"); IP_VS_DBG_PKT(11, af, pp, skb, 0, "Incoming packet");
ipvs = net_ipvs(net);
/* Check the server status */ /* Check the server status */
if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) { if (cp->dest && !(cp->dest->flags & IP_VS_DEST_F_AVAILABLE)) {
/* the destination server is not available */ /* the destination server is not available */
...@@ -1815,13 +1813,15 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb, ...@@ -1815,13 +1813,15 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff *skb,
{ {
int r; int r;
struct net *net; struct net *net;
struct netns_ipvs *ipvs;
if (ip_hdr(skb)->protocol != IPPROTO_ICMP) if (ip_hdr(skb)->protocol != IPPROTO_ICMP)
return NF_ACCEPT; return NF_ACCEPT;
/* ipvs enabled in this netns ? */ /* ipvs enabled in this netns ? */
net = skb_net(skb); net = skb_net(skb);
if (!net_ipvs(net)->enable) ipvs = net_ipvs(net);
if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
return NF_ACCEPT; return NF_ACCEPT;
return ip_vs_in_icmp(skb, &r, hooknum); return ip_vs_in_icmp(skb, &r, hooknum);
...@@ -1835,6 +1835,7 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, ...@@ -1835,6 +1835,7 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
{ {
int r; int r;
struct net *net; struct net *net;
struct netns_ipvs *ipvs;
struct ip_vs_iphdr iphdr; struct ip_vs_iphdr iphdr;
ip_vs_fill_iph_skb(AF_INET6, skb, &iphdr); ip_vs_fill_iph_skb(AF_INET6, skb, &iphdr);
...@@ -1843,7 +1844,8 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb, ...@@ -1843,7 +1844,8 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct sk_buff *skb,
/* ipvs enabled in this netns ? */ /* ipvs enabled in this netns ? */
net = skb_net(skb); net = skb_net(skb);
if (!net_ipvs(net)->enable) ipvs = net_ipvs(net);
if (unlikely(sysctl_backup_only(ipvs) || !ipvs->enable))
return NF_ACCEPT; return NF_ACCEPT;
return ip_vs_in_icmp_v6(skb, &r, hooknum, &iphdr); return ip_vs_in_icmp_v6(skb, &r, hooknum, &iphdr);
......
...@@ -1808,6 +1808,12 @@ static struct ctl_table vs_vars[] = { ...@@ -1808,6 +1808,12 @@ static struct ctl_table vs_vars[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_dointvec, .proc_handler = proc_dointvec,
}, },
{
.procname = "backup_only",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
#ifdef CONFIG_IP_VS_DEBUG #ifdef CONFIG_IP_VS_DEBUG
{ {
.procname = "debug_level", .procname = "debug_level",
...@@ -3741,6 +3747,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net) ...@@ -3741,6 +3747,7 @@ static int __net_init ip_vs_control_net_init_sysctl(struct net *net)
tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; tbl[idx++].data = &ipvs->sysctl_nat_icmp_send;
ipvs->sysctl_pmtu_disc = 1; ipvs->sysctl_pmtu_disc = 1;
tbl[idx++].data = &ipvs->sysctl_pmtu_disc; tbl[idx++].data = &ipvs->sysctl_pmtu_disc;
tbl[idx++].data = &ipvs->sysctl_backup_only;
ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl); ipvs->sysctl_hdr = register_net_sysctl(net, "net/ipv4/vs", tbl);
......
...@@ -906,7 +906,7 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp, ...@@ -906,7 +906,7 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
sctp_chunkhdr_t _sctpch, *sch; sctp_chunkhdr_t _sctpch, *sch;
unsigned char chunk_type; unsigned char chunk_type;
int event, next_state; int event, next_state;
int ihl; int ihl, cofs;
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr); ihl = cp->af == AF_INET ? ip_hdrlen(skb) : sizeof(struct ipv6hdr);
...@@ -914,8 +914,8 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp, ...@@ -914,8 +914,8 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
ihl = ip_hdrlen(skb); ihl = ip_hdrlen(skb);
#endif #endif
sch = skb_header_pointer(skb, ihl + sizeof(sctp_sctphdr_t), cofs = ihl + sizeof(sctp_sctphdr_t);
sizeof(_sctpch), &_sctpch); sch = skb_header_pointer(skb, cofs, sizeof(_sctpch), &_sctpch);
if (sch == NULL) if (sch == NULL)
return; return;
...@@ -933,10 +933,12 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp, ...@@ -933,10 +933,12 @@ set_sctp_state(struct ip_vs_proto_data *pd, struct ip_vs_conn *cp,
*/ */
if ((sch->type == SCTP_CID_COOKIE_ECHO) || if ((sch->type == SCTP_CID_COOKIE_ECHO) ||
(sch->type == SCTP_CID_COOKIE_ACK)) { (sch->type == SCTP_CID_COOKIE_ACK)) {
sch = skb_header_pointer(skb, (ihl + sizeof(sctp_sctphdr_t) + int clen = ntohs(sch->length);
sch->length), sizeof(_sctpch), &_sctpch);
if (sch) { if (clen >= sizeof(sctp_chunkhdr_t)) {
if (sch->type == SCTP_CID_ABORT) sch = skb_header_pointer(skb, cofs + ALIGN(clen, 4),
sizeof(_sctpch), &_sctpch);
if (sch && sch->type == SCTP_CID_ABORT)
chunk_type = sch->type; chunk_type = sch->type;
} }
} }
......
...@@ -969,6 +969,10 @@ static int __init nf_conntrack_proto_dccp_init(void) ...@@ -969,6 +969,10 @@ static int __init nf_conntrack_proto_dccp_init(void)
{ {
int ret; int ret;
ret = register_pernet_subsys(&dccp_net_ops);
if (ret < 0)
goto out_pernet;
ret = nf_ct_l4proto_register(&dccp_proto4); ret = nf_ct_l4proto_register(&dccp_proto4);
if (ret < 0) if (ret < 0)
goto out_dccp4; goto out_dccp4;
...@@ -977,16 +981,12 @@ static int __init nf_conntrack_proto_dccp_init(void) ...@@ -977,16 +981,12 @@ static int __init nf_conntrack_proto_dccp_init(void)
if (ret < 0) if (ret < 0)
goto out_dccp6; goto out_dccp6;
ret = register_pernet_subsys(&dccp_net_ops);
if (ret < 0)
goto out_pernet;
return 0; return 0;
out_pernet:
nf_ct_l4proto_unregister(&dccp_proto6);
out_dccp6: out_dccp6:
nf_ct_l4proto_unregister(&dccp_proto4); nf_ct_l4proto_unregister(&dccp_proto4);
out_dccp4: out_dccp4:
unregister_pernet_subsys(&dccp_net_ops);
out_pernet:
return ret; return ret;
} }
......
...@@ -420,18 +420,18 @@ static int __init nf_ct_proto_gre_init(void) ...@@ -420,18 +420,18 @@ static int __init nf_ct_proto_gre_init(void)
{ {
int ret; int ret;
ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
if (ret < 0)
goto out_gre4;
ret = register_pernet_subsys(&proto_gre_net_ops); ret = register_pernet_subsys(&proto_gre_net_ops);
if (ret < 0) if (ret < 0)
goto out_pernet; goto out_pernet;
ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_gre4);
if (ret < 0)
goto out_gre4;
return 0; return 0;
out_pernet:
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_gre4);
out_gre4: out_gre4:
unregister_pernet_subsys(&proto_gre_net_ops);
out_pernet:
return ret; return ret;
} }
......
...@@ -888,6 +888,10 @@ static int __init nf_conntrack_proto_sctp_init(void) ...@@ -888,6 +888,10 @@ static int __init nf_conntrack_proto_sctp_init(void)
{ {
int ret; int ret;
ret = register_pernet_subsys(&sctp_net_ops);
if (ret < 0)
goto out_pernet;
ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp4); ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_sctp4);
if (ret < 0) if (ret < 0)
goto out_sctp4; goto out_sctp4;
...@@ -896,16 +900,12 @@ static int __init nf_conntrack_proto_sctp_init(void) ...@@ -896,16 +900,12 @@ static int __init nf_conntrack_proto_sctp_init(void)
if (ret < 0) if (ret < 0)
goto out_sctp6; goto out_sctp6;
ret = register_pernet_subsys(&sctp_net_ops);
if (ret < 0)
goto out_pernet;
return 0; return 0;
out_pernet:
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp6);
out_sctp6: out_sctp6:
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4); nf_ct_l4proto_unregister(&nf_conntrack_l4proto_sctp4);
out_sctp4: out_sctp4:
unregister_pernet_subsys(&sctp_net_ops);
out_pernet:
return ret; return ret;
} }
......
...@@ -371,6 +371,10 @@ static int __init nf_conntrack_proto_udplite_init(void) ...@@ -371,6 +371,10 @@ static int __init nf_conntrack_proto_udplite_init(void)
{ {
int ret; int ret;
ret = register_pernet_subsys(&udplite_net_ops);
if (ret < 0)
goto out_pernet;
ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite4); ret = nf_ct_l4proto_register(&nf_conntrack_l4proto_udplite4);
if (ret < 0) if (ret < 0)
goto out_udplite4; goto out_udplite4;
...@@ -379,16 +383,12 @@ static int __init nf_conntrack_proto_udplite_init(void) ...@@ -379,16 +383,12 @@ static int __init nf_conntrack_proto_udplite_init(void)
if (ret < 0) if (ret < 0)
goto out_udplite6; goto out_udplite6;
ret = register_pernet_subsys(&udplite_net_ops);
if (ret < 0)
goto out_pernet;
return 0; return 0;
out_pernet:
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite6);
out_udplite6: out_udplite6:
nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4); nf_ct_l4proto_unregister(&nf_conntrack_l4proto_udplite4);
out_udplite4: out_udplite4:
unregister_pernet_subsys(&udplite_net_ops);
out_pernet:
return ret; return ret;
} }
......
...@@ -112,7 +112,7 @@ instance_create(u_int16_t queue_num, int portid) ...@@ -112,7 +112,7 @@ instance_create(u_int16_t queue_num, int portid)
inst->queue_num = queue_num; inst->queue_num = queue_num;
inst->peer_portid = portid; inst->peer_portid = portid;
inst->queue_maxlen = NFQNL_QMAX_DEFAULT; inst->queue_maxlen = NFQNL_QMAX_DEFAULT;
inst->copy_range = 0xfffff; inst->copy_range = 0xffff;
inst->copy_mode = NFQNL_COPY_NONE; inst->copy_mode = NFQNL_COPY_NONE;
spin_lock_init(&inst->lock); spin_lock_init(&inst->lock);
INIT_LIST_HEAD(&inst->queue_list); INIT_LIST_HEAD(&inst->queue_list);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册