Commit 9bb862be authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://1984.lsi.us.es/net-next

parents b44907e6 d16cf20e
What: ip_queue
Date: finally removed in kernel v3.5.0
Contact: Pablo Neira Ayuso <pablo@netfilter.org>
Description:
ip_queue has been replaced by nfnetlink_queue which provides
more advanced queueing mechanism to user-space. The ip_queue
module was already announced to become obsolete years ago.
Users:
...@@ -1301,13 +1301,22 @@ bridge-nf-call-ip6tables - BOOLEAN ...@@ -1301,13 +1301,22 @@ bridge-nf-call-ip6tables - BOOLEAN
bridge-nf-filter-vlan-tagged - BOOLEAN bridge-nf-filter-vlan-tagged - BOOLEAN
1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables. 1 : pass bridged vlan-tagged ARP/IP/IPv6 traffic to {arp,ip,ip6}tables.
0 : disable this. 0 : disable this.
Default: 1 Default: 0
bridge-nf-filter-pppoe-tagged - BOOLEAN bridge-nf-filter-pppoe-tagged - BOOLEAN
1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables. 1 : pass bridged pppoe-tagged IP/IPv6 traffic to {ip,ip6}tables.
0 : disable this. 0 : disable this.
Default: 1 Default: 0
bridge-nf-pass-vlan-input-dev - BOOLEAN
1: if bridge-nf-filter-vlan-tagged is enabled, try to find a vlan
interface on the bridge and set the netfilter input device to the vlan.
This allows use of e.g. "iptables -i br0.1" and makes the REDIRECT
target work with vlan-on-top-of-bridge interfaces. When no matching
vlan interface is found, or this switch is off, the input device is
set to the bridge interface.
0: disable bridge netfilter vlan interface lookup.
Default: 0
proc/sys/net/sctp/* Variables: proc/sys/net/sctp/* Variables:
......
...@@ -89,6 +89,7 @@ ...@@ -89,6 +89,7 @@
#define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */ #define IP_VS_CONN_F_TEMPLATE 0x1000 /* template, not connection */
#define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */ #define IP_VS_CONN_F_ONE_PACKET 0x2000 /* forward only one packet */
/* Initial bits allowed in backup server */
#define IP_VS_CONN_F_BACKUP_MASK (IP_VS_CONN_F_FWD_MASK | \ #define IP_VS_CONN_F_BACKUP_MASK (IP_VS_CONN_F_FWD_MASK | \
IP_VS_CONN_F_NOOUTPUT | \ IP_VS_CONN_F_NOOUTPUT | \
IP_VS_CONN_F_INACTIVE | \ IP_VS_CONN_F_INACTIVE | \
...@@ -97,6 +98,10 @@ ...@@ -97,6 +98,10 @@
IP_VS_CONN_F_TEMPLATE \ IP_VS_CONN_F_TEMPLATE \
) )
/* Bits allowed to update in backup server */
#define IP_VS_CONN_F_BACKUP_UPD_MASK (IP_VS_CONN_F_INACTIVE | \
IP_VS_CONN_F_SEQ_MASK)
/* Flags that are not sent to backup server start from bit 16 */ /* Flags that are not sent to backup server start from bit 16 */
#define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */ #define IP_VS_CONN_F_NFCT (1 << 16) /* use netfilter conntrack */
......
...@@ -83,6 +83,10 @@ enum ip_conntrack_status { ...@@ -83,6 +83,10 @@ enum ip_conntrack_status {
/* Conntrack is a fake untracked entry */ /* Conntrack is a fake untracked entry */
IPS_UNTRACKED_BIT = 12, IPS_UNTRACKED_BIT = 12,
IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT), IPS_UNTRACKED = (1 << IPS_UNTRACKED_BIT),
/* Conntrack got a helper explicitly attached via CT target. */
IPS_HELPER_BIT = 13,
IPS_HELPER = (1 << IPS_HELPER_BIT),
}; };
/* Connection tracking event types */ /* Connection tracking event types */
......
header-y += ip_queue.h
header-y += ip_tables.h header-y += ip_tables.h
header-y += ipt_CLUSTERIP.h header-y += ipt_CLUSTERIP.h
header-y += ipt_ECN.h header-y += ipt_ECN.h
......
/*
* This is a module which is used for queueing IPv4 packets and
* communicating with userspace via netlink.
*
* (C) 2000 James Morris, this code is GPL.
*/
#ifndef _IP_QUEUE_H
#define _IP_QUEUE_H
#ifdef __KERNEL__
#ifdef DEBUG_IPQ
#define QDEBUG(x...) printk(KERN_DEBUG ## x)
#else
#define QDEBUG(x...)
#endif /* DEBUG_IPQ */
#else
#include <net/if.h>
#endif /* ! __KERNEL__ */
/* Messages sent from kernel */
typedef struct ipq_packet_msg {
unsigned long packet_id; /* ID of queued packet */
unsigned long mark; /* Netfilter mark value */
long timestamp_sec; /* Packet arrival time (seconds) */
long timestamp_usec; /* Packet arrvial time (+useconds) */
unsigned int hook; /* Netfilter hook we rode in on */
char indev_name[IFNAMSIZ]; /* Name of incoming interface */
char outdev_name[IFNAMSIZ]; /* Name of outgoing interface */
__be16 hw_protocol; /* Hardware protocol (network order) */
unsigned short hw_type; /* Hardware type */
unsigned char hw_addrlen; /* Hardware address length */
unsigned char hw_addr[8]; /* Hardware address */
size_t data_len; /* Length of packet data */
unsigned char payload[0]; /* Optional packet data */
} ipq_packet_msg_t;
/* Messages sent from userspace */
typedef struct ipq_mode_msg {
unsigned char value; /* Requested mode */
size_t range; /* Optional range of packet requested */
} ipq_mode_msg_t;
typedef struct ipq_verdict_msg {
unsigned int value; /* Verdict to hand to netfilter */
unsigned long id; /* Packet ID for this verdict */
size_t data_len; /* Length of replacement data */
unsigned char payload[0]; /* Optional replacement packet */
} ipq_verdict_msg_t;
typedef struct ipq_peer_msg {
union {
ipq_verdict_msg_t verdict;
ipq_mode_msg_t mode;
} msg;
} ipq_peer_msg_t;
/* Packet delivery modes */
enum {
IPQ_COPY_NONE, /* Initial mode, packets are dropped */
IPQ_COPY_META, /* Copy metadata */
IPQ_COPY_PACKET /* Copy metadata + packet (range) */
};
#define IPQ_COPY_MAX IPQ_COPY_PACKET
/* Types of messages */
#define IPQM_BASE 0x10 /* standard netlink messages below this */
#define IPQM_MODE (IPQM_BASE + 1) /* Mode request from peer */
#define IPQM_VERDICT (IPQM_BASE + 2) /* Verdict from peer */
#define IPQM_PACKET (IPQM_BASE + 3) /* Packet from kernel */
#define IPQM_MAX (IPQM_BASE + 4)
#endif /*_IP_QUEUE_H*/
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
#define NETLINK_ROUTE 0 /* Routing/device hook */ #define NETLINK_ROUTE 0 /* Routing/device hook */
#define NETLINK_UNUSED 1 /* Unused number */ #define NETLINK_UNUSED 1 /* Unused number */
#define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */ #define NETLINK_USERSOCK 2 /* Reserved for user mode socket protocols */
#define NETLINK_FIREWALL 3 /* Firewalling hook */ #define NETLINK_FIREWALL 3 /* Unused number, formerly ip_queue */
#define NETLINK_SOCK_DIAG 4 /* socket monitoring */ #define NETLINK_SOCK_DIAG 4 /* socket monitoring */
#define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */ #define NETLINK_NFLOG 5 /* netfilter/iptables ULOG */
#define NETLINK_XFRM 6 /* ipsec */ #define NETLINK_XFRM 6 /* ipsec */
......
...@@ -504,6 +504,7 @@ struct ip_vs_conn { ...@@ -504,6 +504,7 @@ struct ip_vs_conn {
* state transition triggerd * state transition triggerd
* synchronization * synchronization
*/ */
unsigned long sync_endtime; /* jiffies + sent_retries */
/* Control members */ /* Control members */
struct ip_vs_conn *control; /* Master control connection */ struct ip_vs_conn *control; /* Master control connection */
...@@ -783,6 +784,16 @@ struct ip_vs_app { ...@@ -783,6 +784,16 @@ struct ip_vs_app {
void (*timeout_change)(struct ip_vs_app *app, int flags); void (*timeout_change)(struct ip_vs_app *app, int flags);
}; };
struct ipvs_master_sync_state {
struct list_head sync_queue;
struct ip_vs_sync_buff *sync_buff;
int sync_queue_len;
unsigned int sync_queue_delay;
struct task_struct *master_thread;
struct delayed_work master_wakeup_work;
struct netns_ipvs *ipvs;
};
/* IPVS in network namespace */ /* IPVS in network namespace */
struct netns_ipvs { struct netns_ipvs {
int gen; /* Generation */ int gen; /* Generation */
...@@ -869,10 +880,15 @@ struct netns_ipvs { ...@@ -869,10 +880,15 @@ struct netns_ipvs {
#endif #endif
int sysctl_snat_reroute; int sysctl_snat_reroute;
int sysctl_sync_ver; int sysctl_sync_ver;
int sysctl_sync_ports;
int sysctl_sync_qlen_max;
int sysctl_sync_sock_size;
int sysctl_cache_bypass; int sysctl_cache_bypass;
int sysctl_expire_nodest_conn; int sysctl_expire_nodest_conn;
int sysctl_expire_quiescent_template; int sysctl_expire_quiescent_template;
int sysctl_sync_threshold[2]; int sysctl_sync_threshold[2];
unsigned int sysctl_sync_refresh_period;
int sysctl_sync_retries;
int sysctl_nat_icmp_send; int sysctl_nat_icmp_send;
/* ip_vs_lblc */ /* ip_vs_lblc */
...@@ -888,13 +904,11 @@ struct netns_ipvs { ...@@ -888,13 +904,11 @@ struct netns_ipvs {
spinlock_t est_lock; spinlock_t est_lock;
struct timer_list est_timer; /* Estimation timer */ struct timer_list est_timer; /* Estimation timer */
/* ip_vs_sync */ /* ip_vs_sync */
struct list_head sync_queue;
spinlock_t sync_lock; spinlock_t sync_lock;
struct ip_vs_sync_buff *sync_buff; struct ipvs_master_sync_state *ms;
spinlock_t sync_buff_lock; spinlock_t sync_buff_lock;
struct sockaddr_in sync_mcast_addr; struct task_struct **backup_threads;
struct task_struct *master_thread; int threads_mask;
struct task_struct *backup_thread;
int send_mesg_maxlen; int send_mesg_maxlen;
int recv_mesg_maxlen; int recv_mesg_maxlen;
volatile int sync_state; volatile int sync_state;
...@@ -911,6 +925,14 @@ struct netns_ipvs { ...@@ -911,6 +925,14 @@ struct netns_ipvs {
#define DEFAULT_SYNC_THRESHOLD 3 #define DEFAULT_SYNC_THRESHOLD 3
#define DEFAULT_SYNC_PERIOD 50 #define DEFAULT_SYNC_PERIOD 50
#define DEFAULT_SYNC_VER 1 #define DEFAULT_SYNC_VER 1
#define DEFAULT_SYNC_REFRESH_PERIOD (0U * HZ)
#define DEFAULT_SYNC_RETRIES 0
#define IPVS_SYNC_WAKEUP_RATE 8
#define IPVS_SYNC_QLEN_MAX (IPVS_SYNC_WAKEUP_RATE * 4)
#define IPVS_SYNC_SEND_DELAY (HZ / 50)
#define IPVS_SYNC_CHECK_PERIOD HZ
#define IPVS_SYNC_FLUSH_TIME (HZ * 2)
#define IPVS_SYNC_PORTS_MAX (1 << 6)
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
...@@ -921,7 +943,17 @@ static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) ...@@ -921,7 +943,17 @@ static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
static inline int sysctl_sync_period(struct netns_ipvs *ipvs) static inline int sysctl_sync_period(struct netns_ipvs *ipvs)
{ {
return ipvs->sysctl_sync_threshold[1]; return ACCESS_ONCE(ipvs->sysctl_sync_threshold[1]);
}
static inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs)
{
return ACCESS_ONCE(ipvs->sysctl_sync_refresh_period);
}
static inline int sysctl_sync_retries(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_sync_retries;
} }
static inline int sysctl_sync_ver(struct netns_ipvs *ipvs) static inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
...@@ -929,6 +961,21 @@ static inline int sysctl_sync_ver(struct netns_ipvs *ipvs) ...@@ -929,6 +961,21 @@ static inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
return ipvs->sysctl_sync_ver; return ipvs->sysctl_sync_ver;
} }
static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
{
return ACCESS_ONCE(ipvs->sysctl_sync_ports);
}
static inline int sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_sync_qlen_max;
}
static inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs)
{
return ipvs->sysctl_sync_sock_size;
}
#else #else
static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs) static inline int sysctl_sync_threshold(struct netns_ipvs *ipvs)
...@@ -941,11 +988,36 @@ static inline int sysctl_sync_period(struct netns_ipvs *ipvs) ...@@ -941,11 +988,36 @@ static inline int sysctl_sync_period(struct netns_ipvs *ipvs)
return DEFAULT_SYNC_PERIOD; return DEFAULT_SYNC_PERIOD;
} }
static inline unsigned int sysctl_sync_refresh_period(struct netns_ipvs *ipvs)
{
return DEFAULT_SYNC_REFRESH_PERIOD;
}
static inline int sysctl_sync_retries(struct netns_ipvs *ipvs)
{
return DEFAULT_SYNC_RETRIES & 3;
}
static inline int sysctl_sync_ver(struct netns_ipvs *ipvs) static inline int sysctl_sync_ver(struct netns_ipvs *ipvs)
{ {
return DEFAULT_SYNC_VER; return DEFAULT_SYNC_VER;
} }
static inline int sysctl_sync_ports(struct netns_ipvs *ipvs)
{
return 1;
}
static inline int sysctl_sync_qlen_max(struct netns_ipvs *ipvs)
{
return IPVS_SYNC_QLEN_MAX;
}
static inline int sysctl_sync_sock_size(struct netns_ipvs *ipvs)
{
return 0;
}
#endif #endif
/* /*
...@@ -1185,7 +1257,6 @@ extern void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg); ...@@ -1185,7 +1257,6 @@ extern void ip_vs_scheduler_err(struct ip_vs_service *svc, const char *msg);
extern struct ip_vs_stats ip_vs_stats; extern struct ip_vs_stats ip_vs_stats;
extern int sysctl_ip_vs_sync_ver; extern int sysctl_ip_vs_sync_ver;
extern void ip_vs_sync_switch_mode(struct net *net, int mode);
extern struct ip_vs_service * extern struct ip_vs_service *
ip_vs_service_get(struct net *net, int af, __u32 fwmark, __u16 protocol, ip_vs_service_get(struct net *net, int af, __u32 fwmark, __u16 protocol,
const union nf_inet_addr *vaddr, __be16 vport); const union nf_inet_addr *vaddr, __be16 vport);
...@@ -1219,7 +1290,7 @@ extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp); ...@@ -1219,7 +1290,7 @@ extern struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp);
extern int start_sync_thread(struct net *net, int state, char *mcast_ifn, extern int start_sync_thread(struct net *net, int state, char *mcast_ifn,
__u8 syncid); __u8 syncid);
extern int stop_sync_thread(struct net *net, int state); extern int stop_sync_thread(struct net *net, int state);
extern void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp); extern void ip_vs_sync_conn(struct net *net, struct ip_vs_conn *cp, int pkts);
/* /*
......
...@@ -321,14 +321,8 @@ extern unsigned int nf_conntrack_max; ...@@ -321,14 +321,8 @@ extern unsigned int nf_conntrack_max;
extern unsigned int nf_conntrack_hash_rnd; extern unsigned int nf_conntrack_hash_rnd;
void init_nf_conntrack_hash_rnd(void); void init_nf_conntrack_hash_rnd(void);
#define NF_CT_STAT_INC(net, count) \ #define NF_CT_STAT_INC(net, count) __this_cpu_inc((net)->ct.stat->count)
__this_cpu_inc((net)->ct.stat->count) #define NF_CT_STAT_INC_ATOMIC(net, count) this_cpu_inc((net)->ct.stat->count)
#define NF_CT_STAT_INC_ATOMIC(net, count) \
do { \
local_bh_disable(); \
__this_cpu_inc((net)->ct.stat->count); \
local_bh_enable(); \
} while (0)
#define MODULE_ALIAS_NFCT_HELPER(helper) \ #define MODULE_ALIAS_NFCT_HELPER(helper) \
MODULE_ALIAS("nfct-helper-" helper) MODULE_ALIAS("nfct-helper-" helper)
......
...@@ -60,8 +60,8 @@ static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct) ...@@ -60,8 +60,8 @@ static inline struct nf_conn_help *nfct_help(const struct nf_conn *ct)
return nf_ct_ext_find(ct, NF_CT_EXT_HELPER); return nf_ct_ext_find(ct, NF_CT_EXT_HELPER);
} }
extern int nf_conntrack_helper_init(void); extern int nf_conntrack_helper_init(struct net *net);
extern void nf_conntrack_helper_fini(void); extern void nf_conntrack_helper_fini(struct net *net);
extern int nf_conntrack_broadcast_help(struct sk_buff *skb, extern int nf_conntrack_broadcast_help(struct sk_buff *skb,
unsigned int protoff, unsigned int protoff,
......
...@@ -26,11 +26,14 @@ struct netns_ct { ...@@ -26,11 +26,14 @@ struct netns_ct {
int sysctl_tstamp; int sysctl_tstamp;
int sysctl_checksum; int sysctl_checksum;
unsigned int sysctl_log_invalid; /* Log invalid packets */ unsigned int sysctl_log_invalid; /* Log invalid packets */
int sysctl_auto_assign_helper;
bool auto_assign_helper_warned;
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
struct ctl_table_header *sysctl_header; struct ctl_table_header *sysctl_header;
struct ctl_table_header *acct_sysctl_header; struct ctl_table_header *acct_sysctl_header;
struct ctl_table_header *tstamp_sysctl_header; struct ctl_table_header *tstamp_sysctl_header;
struct ctl_table_header *event_sysctl_header; struct ctl_table_header *event_sysctl_header;
struct ctl_table_header *helper_sysctl_header;
#endif #endif
char *slabname; char *slabname;
}; };
......
...@@ -54,12 +54,14 @@ static int brnf_call_ip6tables __read_mostly = 1; ...@@ -54,12 +54,14 @@ static int brnf_call_ip6tables __read_mostly = 1;
static int brnf_call_arptables __read_mostly = 1; static int brnf_call_arptables __read_mostly = 1;
static int brnf_filter_vlan_tagged __read_mostly = 0; static int brnf_filter_vlan_tagged __read_mostly = 0;
static int brnf_filter_pppoe_tagged __read_mostly = 0; static int brnf_filter_pppoe_tagged __read_mostly = 0;
static int brnf_pass_vlan_indev __read_mostly = 0;
#else #else
#define brnf_call_iptables 1 #define brnf_call_iptables 1
#define brnf_call_ip6tables 1 #define brnf_call_ip6tables 1
#define brnf_call_arptables 1 #define brnf_call_arptables 1
#define brnf_filter_vlan_tagged 0 #define brnf_filter_vlan_tagged 0
#define brnf_filter_pppoe_tagged 0 #define brnf_filter_pppoe_tagged 0
#define brnf_pass_vlan_indev 0
#endif #endif
#define IS_IP(skb) \ #define IS_IP(skb) \
...@@ -503,6 +505,19 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb) ...@@ -503,6 +505,19 @@ static int br_nf_pre_routing_finish(struct sk_buff *skb)
return 0; return 0;
} }
static struct net_device *brnf_get_logical_dev(struct sk_buff *skb, const struct net_device *dev)
{
struct net_device *vlan, *br;
br = bridge_parent(dev);
if (brnf_pass_vlan_indev == 0 || !vlan_tx_tag_present(skb))
return br;
vlan = __vlan_find_dev_deep(br, vlan_tx_tag_get(skb) & VLAN_VID_MASK);
return vlan ? vlan : br;
}
/* Some common code for IPv4/IPv6 */ /* Some common code for IPv4/IPv6 */
static struct net_device *setup_pre_routing(struct sk_buff *skb) static struct net_device *setup_pre_routing(struct sk_buff *skb)
{ {
...@@ -515,7 +530,7 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb) ...@@ -515,7 +530,7 @@ static struct net_device *setup_pre_routing(struct sk_buff *skb)
nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING; nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
nf_bridge->physindev = skb->dev; nf_bridge->physindev = skb->dev;
skb->dev = bridge_parent(skb->dev); skb->dev = brnf_get_logical_dev(skb, skb->dev);
if (skb->protocol == htons(ETH_P_8021Q)) if (skb->protocol == htons(ETH_P_8021Q))
nf_bridge->mask |= BRNF_8021Q; nf_bridge->mask |= BRNF_8021Q;
else if (skb->protocol == htons(ETH_P_PPP_SES)) else if (skb->protocol == htons(ETH_P_PPP_SES))
...@@ -774,7 +789,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb, ...@@ -774,7 +789,7 @@ static unsigned int br_nf_forward_ip(unsigned int hook, struct sk_buff *skb,
else else
skb->protocol = htons(ETH_P_IPV6); skb->protocol = htons(ETH_P_IPV6);
NF_HOOK(pf, NF_INET_FORWARD, skb, bridge_parent(in), parent, NF_HOOK(pf, NF_INET_FORWARD, skb, brnf_get_logical_dev(skb, in), parent,
br_nf_forward_finish); br_nf_forward_finish);
return NF_STOLEN; return NF_STOLEN;
...@@ -1002,6 +1017,13 @@ static ctl_table brnf_table[] = { ...@@ -1002,6 +1017,13 @@ static ctl_table brnf_table[] = {
.mode = 0644, .mode = 0644,
.proc_handler = brnf_sysctl_call_tables, .proc_handler = brnf_sysctl_call_tables,
}, },
{
.procname = "bridge-nf-pass-vlan-input-dev",
.data = &brnf_pass_vlan_indev,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = brnf_sysctl_call_tables,
},
{ } { }
}; };
#endif #endif
......
...@@ -259,7 +259,9 @@ static struct lock_class_key af_callback_keys[AF_MAX]; ...@@ -259,7 +259,9 @@ static struct lock_class_key af_callback_keys[AF_MAX];
/* Run time adjustable parameters. */ /* Run time adjustable parameters. */
__u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX; __u32 sysctl_wmem_max __read_mostly = SK_WMEM_MAX;
EXPORT_SYMBOL(sysctl_wmem_max);
__u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX; __u32 sysctl_rmem_max __read_mostly = SK_RMEM_MAX;
EXPORT_SYMBOL(sysctl_rmem_max);
__u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX; __u32 sysctl_wmem_default __read_mostly = SK_WMEM_MAX;
__u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX; __u32 sysctl_rmem_default __read_mostly = SK_RMEM_MAX;
......
...@@ -66,6 +66,3 @@ obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o ...@@ -66,6 +66,3 @@ obj-$(CONFIG_IP_NF_ARP_MANGLE) += arpt_mangle.o
# just filtering instance of ARP tables for now # just filtering instance of ARP tables for now
obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o obj-$(CONFIG_IP_NF_ARPFILTER) += arptable_filter.o
obj-$(CONFIG_IP_NF_QUEUE) += ip_queue.o
This diff is collapsed.
...@@ -25,28 +25,6 @@ config NF_CONNTRACK_IPV6 ...@@ -25,28 +25,6 @@ config NF_CONNTRACK_IPV6
To compile it as a module, choose M here. If unsure, say N. To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_QUEUE
tristate "IP6 Userspace queueing via NETLINK (OBSOLETE)"
depends on INET && IPV6 && NETFILTER
depends on NETFILTER_ADVANCED
---help---
This option adds a queue handler to the kernel for IPv6
packets which enables users to receive the filtered packets
with QUEUE target using libipq.
This option enables the old IPv6-only "ip6_queue" implementation
which has been obsoleted by the new "nfnetlink_queue" code (see
CONFIG_NETFILTER_NETLINK_QUEUE).
(C) Fernando Anton 2001
IPv64 Project - Work based in IPv64 draft by Arturo Azcorra.
Universidad Carlos III de Madrid
Universidad Politecnica de Alcala de Henares
email: <fanton@it.uc3m.es>.
To compile it as a module, choose M here. If unsure, say N.
config IP6_NF_IPTABLES config IP6_NF_IPTABLES
tristate "IP6 tables support (required for filtering)" tristate "IP6 tables support (required for filtering)"
depends on INET && IPV6 depends on INET && IPV6
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o obj-$(CONFIG_IP6_NF_IPTABLES) += ip6_tables.o
obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o obj-$(CONFIG_IP6_NF_FILTER) += ip6table_filter.o
obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o obj-$(CONFIG_IP6_NF_MANGLE) += ip6table_mangle.o
obj-$(CONFIG_IP6_NF_QUEUE) += ip6_queue.o
obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o obj-$(CONFIG_IP6_NF_RAW) += ip6table_raw.o
obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o obj-$(CONFIG_IP6_NF_SECURITY) += ip6table_security.o
......
This diff is collapsed.
...@@ -548,6 +548,7 @@ static inline void ...@@ -548,6 +548,7 @@ static inline void
ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
{ {
unsigned int conn_flags; unsigned int conn_flags;
__u32 flags;
/* if dest is NULL, then return directly */ /* if dest is NULL, then return directly */
if (!dest) if (!dest)
...@@ -559,17 +560,19 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) ...@@ -559,17 +560,19 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
conn_flags = atomic_read(&dest->conn_flags); conn_flags = atomic_read(&dest->conn_flags);
if (cp->protocol != IPPROTO_UDP) if (cp->protocol != IPPROTO_UDP)
conn_flags &= ~IP_VS_CONN_F_ONE_PACKET; conn_flags &= ~IP_VS_CONN_F_ONE_PACKET;
flags = cp->flags;
/* Bind with the destination and its corresponding transmitter */ /* Bind with the destination and its corresponding transmitter */
if (cp->flags & IP_VS_CONN_F_SYNC) { if (flags & IP_VS_CONN_F_SYNC) {
/* if the connection is not template and is created /* if the connection is not template and is created
* by sync, preserve the activity flag. * by sync, preserve the activity flag.
*/ */
if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) if (!(flags & IP_VS_CONN_F_TEMPLATE))
conn_flags &= ~IP_VS_CONN_F_INACTIVE; conn_flags &= ~IP_VS_CONN_F_INACTIVE;
/* connections inherit forwarding method from dest */ /* connections inherit forwarding method from dest */
cp->flags &= ~IP_VS_CONN_F_FWD_MASK; flags &= ~(IP_VS_CONN_F_FWD_MASK | IP_VS_CONN_F_NOOUTPUT);
} }
cp->flags |= conn_flags; flags |= conn_flags;
cp->flags = flags;
cp->dest = dest; cp->dest = dest;
IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d " IP_VS_DBG_BUF(7, "Bind-dest %s c:%s:%d v:%s:%d "
...@@ -584,12 +587,12 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest) ...@@ -584,12 +587,12 @@ ip_vs_bind_dest(struct ip_vs_conn *cp, struct ip_vs_dest *dest)
atomic_read(&dest->refcnt)); atomic_read(&dest->refcnt));
/* Update the connection counters */ /* Update the connection counters */
if (!(cp->flags & IP_VS_CONN_F_TEMPLATE)) { if (!(flags & IP_VS_CONN_F_TEMPLATE)) {
/* It is a normal connection, so increase the inactive /* It is a normal connection, so modify the counters
connection counter because it is in TCP SYNRECV * according to the flags, later the protocol can
state (inactive) or other protocol inacive state */ * update them on state change
if ((cp->flags & IP_VS_CONN_F_SYNC) && */
(!(cp->flags & IP_VS_CONN_F_INACTIVE))) if (!(flags & IP_VS_CONN_F_INACTIVE))
atomic_inc(&dest->activeconns); atomic_inc(&dest->activeconns);
else else
atomic_inc(&dest->inactconns); atomic_inc(&dest->inactconns);
...@@ -613,14 +616,40 @@ struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp) ...@@ -613,14 +616,40 @@ struct ip_vs_dest *ip_vs_try_bind_dest(struct ip_vs_conn *cp)
{ {
struct ip_vs_dest *dest; struct ip_vs_dest *dest;
if ((cp) && (!cp->dest)) { dest = ip_vs_find_dest(ip_vs_conn_net(cp), cp->af, &cp->daddr,
dest = ip_vs_find_dest(ip_vs_conn_net(cp), cp->af, &cp->daddr, cp->dport, &cp->vaddr, cp->vport,
cp->dport, &cp->vaddr, cp->vport, cp->protocol, cp->fwmark, cp->flags);
cp->protocol, cp->fwmark, cp->flags); if (dest) {
struct ip_vs_proto_data *pd;
spin_lock(&cp->lock);
if (cp->dest) {
spin_unlock(&cp->lock);
return dest;
}
/* Applications work depending on the forwarding method
* but better to reassign them always when binding dest */
if (cp->app)
ip_vs_unbind_app(cp);
ip_vs_bind_dest(cp, dest); ip_vs_bind_dest(cp, dest);
return dest; spin_unlock(&cp->lock);
} else
return NULL; /* Update its packet transmitter */
cp->packet_xmit = NULL;
#ifdef CONFIG_IP_VS_IPV6
if (cp->af == AF_INET6)
ip_vs_bind_xmit_v6(cp);
else
#endif
ip_vs_bind_xmit(cp);
pd = ip_vs_proto_data_get(ip_vs_conn_net(cp), cp->protocol);
if (pd && atomic_read(&pd->appcnt))
ip_vs_bind_app(cp, pd->pp);
}
return dest;
} }
...@@ -743,7 +772,8 @@ int ip_vs_check_template(struct ip_vs_conn *ct) ...@@ -743,7 +772,8 @@ int ip_vs_check_template(struct ip_vs_conn *ct)
static void ip_vs_conn_expire(unsigned long data) static void ip_vs_conn_expire(unsigned long data)
{ {
struct ip_vs_conn *cp = (struct ip_vs_conn *)data; struct ip_vs_conn *cp = (struct ip_vs_conn *)data;
struct netns_ipvs *ipvs = net_ipvs(ip_vs_conn_net(cp)); struct net *net = ip_vs_conn_net(cp);
struct netns_ipvs *ipvs = net_ipvs(net);
cp->timeout = 60*HZ; cp->timeout = 60*HZ;
...@@ -808,6 +838,9 @@ static void ip_vs_conn_expire(unsigned long data) ...@@ -808,6 +838,9 @@ static void ip_vs_conn_expire(unsigned long data)
atomic_read(&cp->refcnt)-1, atomic_read(&cp->refcnt)-1,
atomic_read(&cp->n_control)); atomic_read(&cp->n_control));
if (ipvs->sync_state & IP_VS_STATE_MASTER)
ip_vs_sync_conn(net, cp, sysctl_sync_threshold(ipvs));
ip_vs_conn_put(cp); ip_vs_conn_put(cp);
} }
...@@ -881,6 +914,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p, ...@@ -881,6 +914,7 @@ ip_vs_conn_new(const struct ip_vs_conn_param *p,
/* Set its state and timeout */ /* Set its state and timeout */
cp->state = 0; cp->state = 0;
cp->timeout = 3*HZ; cp->timeout = 3*HZ;
cp->sync_endtime = jiffies & ~3UL;
/* Bind its packet transmitter */ /* Bind its packet transmitter */
#ifdef CONFIG_IP_VS_IPV6 #ifdef CONFIG_IP_VS_IPV6
......
...@@ -1613,34 +1613,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af) ...@@ -1613,34 +1613,8 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int af)
else else
pkts = atomic_add_return(1, &cp->in_pkts); pkts = atomic_add_return(1, &cp->in_pkts);
if ((ipvs->sync_state & IP_VS_STATE_MASTER) && if (ipvs->sync_state & IP_VS_STATE_MASTER)
cp->protocol == IPPROTO_SCTP) { ip_vs_sync_conn(net, cp, pkts);
if ((cp->state == IP_VS_SCTP_S_ESTABLISHED &&
(pkts % sysctl_sync_period(ipvs)
== sysctl_sync_threshold(ipvs))) ||
(cp->old_state != cp->state &&
((cp->state == IP_VS_SCTP_S_CLOSED) ||
(cp->state == IP_VS_SCTP_S_SHUT_ACK_CLI) ||
(cp->state == IP_VS_SCTP_S_SHUT_ACK_SER)))) {
ip_vs_sync_conn(net, cp);
goto out;
}
}
/* Keep this block last: TCP and others with pp->num_states <= 1 */
else if ((ipvs->sync_state & IP_VS_STATE_MASTER) &&
(((cp->protocol != IPPROTO_TCP ||
cp->state == IP_VS_TCP_S_ESTABLISHED) &&
(pkts % sysctl_sync_period(ipvs)
== sysctl_sync_threshold(ipvs))) ||
((cp->protocol == IPPROTO_TCP) && (cp->old_state != cp->state) &&
((cp->state == IP_VS_TCP_S_FIN_WAIT) ||
(cp->state == IP_VS_TCP_S_CLOSE) ||
(cp->state == IP_VS_TCP_S_CLOSE_WAIT) ||
(cp->state == IP_VS_TCP_S_TIME_WAIT)))))
ip_vs_sync_conn(net, cp);
out:
cp->old_state = cp->state;
ip_vs_conn_put(cp); ip_vs_conn_put(cp);
return ret; return ret;
......
...@@ -1599,6 +1599,10 @@ static int ip_vs_zero_all(struct net *net) ...@@ -1599,6 +1599,10 @@ static int ip_vs_zero_all(struct net *net)
} }
#ifdef CONFIG_SYSCTL #ifdef CONFIG_SYSCTL
static int zero;
static int three = 3;
static int static int
proc_do_defense_mode(ctl_table *table, int write, proc_do_defense_mode(ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos) void __user *buffer, size_t *lenp, loff_t *ppos)
...@@ -1632,7 +1636,8 @@ proc_do_sync_threshold(ctl_table *table, int write, ...@@ -1632,7 +1636,8 @@ proc_do_sync_threshold(ctl_table *table, int write,
memcpy(val, valp, sizeof(val)); memcpy(val, valp, sizeof(val));
rc = proc_dointvec(table, write, buffer, lenp, ppos); rc = proc_dointvec(table, write, buffer, lenp, ppos);
if (write && (valp[0] < 0 || valp[1] < 0 || valp[0] >= valp[1])) { if (write && (valp[0] < 0 || valp[1] < 0 ||
(valp[0] >= valp[1] && valp[1]))) {
/* Restore the correct value */ /* Restore the correct value */
memcpy(valp, val, sizeof(val)); memcpy(valp, val, sizeof(val));
} }
...@@ -1652,9 +1657,24 @@ proc_do_sync_mode(ctl_table *table, int write, ...@@ -1652,9 +1657,24 @@ proc_do_sync_mode(ctl_table *table, int write,
if ((*valp < 0) || (*valp > 1)) { if ((*valp < 0) || (*valp > 1)) {
/* Restore the correct value */ /* Restore the correct value */
*valp = val; *valp = val;
} else { }
struct net *net = current->nsproxy->net_ns; }
ip_vs_sync_switch_mode(net, val); return rc;
}
static int
proc_do_sync_ports(ctl_table *table, int write,
void __user *buffer, size_t *lenp, loff_t *ppos)
{
int *valp = table->data;
int val = *valp;
int rc;
rc = proc_dointvec(table, write, buffer, lenp, ppos);
if (write && (*valp != val)) {
if (*valp < 1 || !is_power_of_2(*valp)) {
/* Restore the correct value */
*valp = val;
} }
} }
return rc; return rc;
...@@ -1717,6 +1737,24 @@ static struct ctl_table vs_vars[] = { ...@@ -1717,6 +1737,24 @@ static struct ctl_table vs_vars[] = {
.mode = 0644, .mode = 0644,
.proc_handler = &proc_do_sync_mode, .proc_handler = &proc_do_sync_mode,
}, },
{
.procname = "sync_ports",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = &proc_do_sync_ports,
},
{
.procname = "sync_qlen_max",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{
.procname = "sync_sock_size",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{ {
.procname = "cache_bypass", .procname = "cache_bypass",
.maxlen = sizeof(int), .maxlen = sizeof(int),
...@@ -1742,6 +1780,20 @@ static struct ctl_table vs_vars[] = { ...@@ -1742,6 +1780,20 @@ static struct ctl_table vs_vars[] = {
.mode = 0644, .mode = 0644,
.proc_handler = proc_do_sync_threshold, .proc_handler = proc_do_sync_threshold,
}, },
{
.procname = "sync_refresh_period",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
},
{
.procname = "sync_retries",
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_minmax,
.extra1 = &zero,
.extra2 = &three,
},
{ {
.procname = "nat_icmp_send", .procname = "nat_icmp_send",
.maxlen = sizeof(int), .maxlen = sizeof(int),
...@@ -3655,6 +3707,12 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net) ...@@ -3655,6 +3707,12 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
tbl[idx++].data = &ipvs->sysctl_snat_reroute; tbl[idx++].data = &ipvs->sysctl_snat_reroute;
ipvs->sysctl_sync_ver = 1; ipvs->sysctl_sync_ver = 1;
tbl[idx++].data = &ipvs->sysctl_sync_ver; tbl[idx++].data = &ipvs->sysctl_sync_ver;
ipvs->sysctl_sync_ports = 1;
tbl[idx++].data = &ipvs->sysctl_sync_ports;
ipvs->sysctl_sync_qlen_max = nr_free_buffer_pages() / 32;
tbl[idx++].data = &ipvs->sysctl_sync_qlen_max;
ipvs->sysctl_sync_sock_size = 0;
tbl[idx++].data = &ipvs->sysctl_sync_sock_size;
tbl[idx++].data = &ipvs->sysctl_cache_bypass; tbl[idx++].data = &ipvs->sysctl_cache_bypass;
tbl[idx++].data = &ipvs->sysctl_expire_nodest_conn; tbl[idx++].data = &ipvs->sysctl_expire_nodest_conn;
tbl[idx++].data = &ipvs->sysctl_expire_quiescent_template; tbl[idx++].data = &ipvs->sysctl_expire_quiescent_template;
...@@ -3662,6 +3720,10 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net) ...@@ -3662,6 +3720,10 @@ int __net_init ip_vs_control_net_init_sysctl(struct net *net)
ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD; ipvs->sysctl_sync_threshold[1] = DEFAULT_SYNC_PERIOD;
tbl[idx].data = &ipvs->sysctl_sync_threshold; tbl[idx].data = &ipvs->sysctl_sync_threshold;
tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold); tbl[idx++].maxlen = sizeof(ipvs->sysctl_sync_threshold);
ipvs->sysctl_sync_refresh_period = DEFAULT_SYNC_REFRESH_PERIOD;
tbl[idx++].data = &ipvs->sysctl_sync_refresh_period;
ipvs->sysctl_sync_retries = clamp_t(int, DEFAULT_SYNC_RETRIES, 0, 3);
tbl[idx++].data = &ipvs->sysctl_sync_retries;
tbl[idx++].data = &ipvs->sysctl_nat_icmp_send; tbl[idx++].data = &ipvs->sysctl_nat_icmp_send;
......
...@@ -149,7 +149,7 @@ static int ip_vs_dh_init_svc(struct ip_vs_service *svc) ...@@ -149,7 +149,7 @@ static int ip_vs_dh_init_svc(struct ip_vs_service *svc)
/* allocate the DH table for this service */ /* allocate the DH table for this service */
tbl = kmalloc(sizeof(struct ip_vs_dh_bucket)*IP_VS_DH_TAB_SIZE, tbl = kmalloc(sizeof(struct ip_vs_dh_bucket)*IP_VS_DH_TAB_SIZE,
GFP_ATOMIC); GFP_KERNEL);
if (tbl == NULL) if (tbl == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -485,7 +485,7 @@ static struct pernet_operations ip_vs_ftp_ops = { ...@@ -485,7 +485,7 @@ static struct pernet_operations ip_vs_ftp_ops = {
.exit = __ip_vs_ftp_exit, .exit = __ip_vs_ftp_exit,
}; };
int __init ip_vs_ftp_init(void) static int __init ip_vs_ftp_init(void)
{ {
int rv; int rv;
......
...@@ -342,7 +342,7 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc) ...@@ -342,7 +342,7 @@ static int ip_vs_lblc_init_svc(struct ip_vs_service *svc)
/* /*
* Allocate the ip_vs_lblc_table for this service * Allocate the ip_vs_lblc_table for this service
*/ */
tbl = kmalloc(sizeof(*tbl), GFP_ATOMIC); tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
if (tbl == NULL) if (tbl == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -511,7 +511,7 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc) ...@@ -511,7 +511,7 @@ static int ip_vs_lblcr_init_svc(struct ip_vs_service *svc)
/* /*
* Allocate the ip_vs_lblcr_table for this service * Allocate the ip_vs_lblcr_table for this service
*/ */
tbl = kmalloc(sizeof(*tbl), GFP_ATOMIC); tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
if (tbl == NULL) if (tbl == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -68,7 +68,7 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp) ...@@ -68,7 +68,7 @@ register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
struct netns_ipvs *ipvs = net_ipvs(net); struct netns_ipvs *ipvs = net_ipvs(net);
unsigned int hash = IP_VS_PROTO_HASH(pp->protocol); unsigned int hash = IP_VS_PROTO_HASH(pp->protocol);
struct ip_vs_proto_data *pd = struct ip_vs_proto_data *pd =
kzalloc(sizeof(struct ip_vs_proto_data), GFP_ATOMIC); kzalloc(sizeof(struct ip_vs_proto_data), GFP_KERNEL);
if (!pd) if (!pd)
return -ENOMEM; return -ENOMEM;
...@@ -156,7 +156,7 @@ EXPORT_SYMBOL(ip_vs_proto_get); ...@@ -156,7 +156,7 @@ EXPORT_SYMBOL(ip_vs_proto_get);
/* /*
* get ip_vs_protocol object data by netns and proto * get ip_vs_protocol object data by netns and proto
*/ */
struct ip_vs_proto_data * static struct ip_vs_proto_data *
__ipvs_proto_data_get(struct netns_ipvs *ipvs, unsigned short proto) __ipvs_proto_data_get(struct netns_ipvs *ipvs, unsigned short proto)
{ {
struct ip_vs_proto_data *pd; struct ip_vs_proto_data *pd;
...@@ -199,7 +199,7 @@ void ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags) ...@@ -199,7 +199,7 @@ void ip_vs_protocol_timeout_change(struct netns_ipvs *ipvs, int flags)
int * int *
ip_vs_create_timeout_table(int *table, int size) ip_vs_create_timeout_table(int *table, int size)
{ {
return kmemdup(table, size, GFP_ATOMIC); return kmemdup(table, size, GFP_KERNEL);
} }
......
...@@ -162,7 +162,7 @@ static int ip_vs_sh_init_svc(struct ip_vs_service *svc) ...@@ -162,7 +162,7 @@ static int ip_vs_sh_init_svc(struct ip_vs_service *svc)
/* allocate the SH table for this service */ /* allocate the SH table for this service */
tbl = kmalloc(sizeof(struct ip_vs_sh_bucket)*IP_VS_SH_TAB_SIZE, tbl = kmalloc(sizeof(struct ip_vs_sh_bucket)*IP_VS_SH_TAB_SIZE,
GFP_ATOMIC); GFP_KERNEL);
if (tbl == NULL) if (tbl == NULL)
return -ENOMEM; return -ENOMEM;
......
This diff is collapsed.
...@@ -84,7 +84,7 @@ static int ip_vs_wrr_init_svc(struct ip_vs_service *svc) ...@@ -84,7 +84,7 @@ static int ip_vs_wrr_init_svc(struct ip_vs_service *svc)
/* /*
* Allocate the mark variable for WRR scheduling * Allocate the mark variable for WRR scheduling
*/ */
mark = kmalloc(sizeof(struct ip_vs_wrr_mark), GFP_ATOMIC); mark = kmalloc(sizeof(struct ip_vs_wrr_mark), GFP_KERNEL);
if (mark == NULL) if (mark == NULL)
return -ENOMEM; return -ENOMEM;
......
...@@ -1336,7 +1336,6 @@ static void nf_conntrack_cleanup_init_net(void) ...@@ -1336,7 +1336,6 @@ static void nf_conntrack_cleanup_init_net(void)
while (untrack_refs() > 0) while (untrack_refs() > 0)
schedule(); schedule();
nf_conntrack_helper_fini();
nf_conntrack_proto_fini(); nf_conntrack_proto_fini();
#ifdef CONFIG_NF_CONNTRACK_ZONES #ifdef CONFIG_NF_CONNTRACK_ZONES
nf_ct_extend_unregister(&nf_ct_zone_extend); nf_ct_extend_unregister(&nf_ct_zone_extend);
...@@ -1354,6 +1353,7 @@ static void nf_conntrack_cleanup_net(struct net *net) ...@@ -1354,6 +1353,7 @@ static void nf_conntrack_cleanup_net(struct net *net)
} }
nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size); nf_ct_free_hashtable(net->ct.hash, net->ct.htable_size);
nf_conntrack_helper_fini(net);
nf_conntrack_timeout_fini(net); nf_conntrack_timeout_fini(net);
nf_conntrack_ecache_fini(net); nf_conntrack_ecache_fini(net);
nf_conntrack_tstamp_fini(net); nf_conntrack_tstamp_fini(net);
...@@ -1504,10 +1504,6 @@ static int nf_conntrack_init_init_net(void) ...@@ -1504,10 +1504,6 @@ static int nf_conntrack_init_init_net(void)
if (ret < 0) if (ret < 0)
goto err_proto; goto err_proto;
ret = nf_conntrack_helper_init();
if (ret < 0)
goto err_helper;
#ifdef CONFIG_NF_CONNTRACK_ZONES #ifdef CONFIG_NF_CONNTRACK_ZONES
ret = nf_ct_extend_register(&nf_ct_zone_extend); ret = nf_ct_extend_register(&nf_ct_zone_extend);
if (ret < 0) if (ret < 0)
...@@ -1525,10 +1521,8 @@ static int nf_conntrack_init_init_net(void) ...@@ -1525,10 +1521,8 @@ static int nf_conntrack_init_init_net(void)
#ifdef CONFIG_NF_CONNTRACK_ZONES #ifdef CONFIG_NF_CONNTRACK_ZONES
err_extend: err_extend:
nf_conntrack_helper_fini();
#endif
err_helper:
nf_conntrack_proto_fini(); nf_conntrack_proto_fini();
#endif
err_proto: err_proto:
return ret; return ret;
} }
...@@ -1589,9 +1583,14 @@ static int nf_conntrack_init_net(struct net *net) ...@@ -1589,9 +1583,14 @@ static int nf_conntrack_init_net(struct net *net)
ret = nf_conntrack_timeout_init(net); ret = nf_conntrack_timeout_init(net);
if (ret < 0) if (ret < 0)
goto err_timeout; goto err_timeout;
ret = nf_conntrack_helper_init(net);
if (ret < 0)
goto err_helper;
return 0; return 0;
err_helper:
nf_conntrack_timeout_fini(net);
err_timeout: err_timeout:
nf_conntrack_ecache_fini(net); nf_conntrack_ecache_fini(net);
err_ecache: err_ecache:
......
...@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events); ...@@ -84,7 +84,7 @@ EXPORT_SYMBOL_GPL(nf_ct_deliver_cached_events);
int nf_conntrack_register_notifier(struct net *net, int nf_conntrack_register_notifier(struct net *net,
struct nf_ct_event_notifier *new) struct nf_ct_event_notifier *new)
{ {
int ret = 0; int ret;
struct nf_ct_event_notifier *notify; struct nf_ct_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
...@@ -95,8 +95,7 @@ int nf_conntrack_register_notifier(struct net *net, ...@@ -95,8 +95,7 @@ int nf_conntrack_register_notifier(struct net *net,
goto out_unlock; goto out_unlock;
} }
rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new); rcu_assign_pointer(net->ct.nf_conntrack_event_cb, new);
mutex_unlock(&nf_ct_ecache_mutex); ret = 0;
return ret;
out_unlock: out_unlock:
mutex_unlock(&nf_ct_ecache_mutex); mutex_unlock(&nf_ct_ecache_mutex);
...@@ -121,7 +120,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier); ...@@ -121,7 +120,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_unregister_notifier);
int nf_ct_expect_register_notifier(struct net *net, int nf_ct_expect_register_notifier(struct net *net,
struct nf_exp_event_notifier *new) struct nf_exp_event_notifier *new)
{ {
int ret = 0; int ret;
struct nf_exp_event_notifier *notify; struct nf_exp_event_notifier *notify;
mutex_lock(&nf_ct_ecache_mutex); mutex_lock(&nf_ct_ecache_mutex);
...@@ -132,8 +131,7 @@ int nf_ct_expect_register_notifier(struct net *net, ...@@ -132,8 +131,7 @@ int nf_ct_expect_register_notifier(struct net *net,
goto out_unlock; goto out_unlock;
} }
rcu_assign_pointer(net->ct.nf_expect_event_cb, new); rcu_assign_pointer(net->ct.nf_expect_event_cb, new);
mutex_unlock(&nf_ct_ecache_mutex); ret = 0;
return ret;
out_unlock: out_unlock:
mutex_unlock(&nf_ct_ecache_mutex); mutex_unlock(&nf_ct_ecache_mutex);
......
...@@ -34,6 +34,67 @@ static struct hlist_head *nf_ct_helper_hash __read_mostly; ...@@ -34,6 +34,67 @@ static struct hlist_head *nf_ct_helper_hash __read_mostly;
static unsigned int nf_ct_helper_hsize __read_mostly; static unsigned int nf_ct_helper_hsize __read_mostly;
static unsigned int nf_ct_helper_count __read_mostly; static unsigned int nf_ct_helper_count __read_mostly;
static bool nf_ct_auto_assign_helper __read_mostly = true;
module_param_named(nf_conntrack_helper, nf_ct_auto_assign_helper, bool, 0644);
MODULE_PARM_DESC(nf_conntrack_helper,
"Enable automatic conntrack helper assignment (default 1)");
#ifdef CONFIG_SYSCTL
static struct ctl_table helper_sysctl_table[] = {
{
.procname = "nf_conntrack_helper",
.data = &init_net.ct.sysctl_auto_assign_helper,
.maxlen = sizeof(unsigned int),
.mode = 0644,
.proc_handler = proc_dointvec,
},
{}
};
static int nf_conntrack_helper_init_sysctl(struct net *net)
{
struct ctl_table *table;
table = kmemdup(helper_sysctl_table, sizeof(helper_sysctl_table),
GFP_KERNEL);
if (!table)
goto out;
table[0].data = &net->ct.sysctl_auto_assign_helper;
net->ct.helper_sysctl_header =
register_net_sysctl(net, "net/netfilter", table);
if (!net->ct.helper_sysctl_header) {
pr_err("nf_conntrack_helper: can't register to sysctl.\n");
goto out_register;
}
return 0;
out_register:
kfree(table);
out:
return -ENOMEM;
}
static void nf_conntrack_helper_fini_sysctl(struct net *net)
{
struct ctl_table *table;
table = net->ct.helper_sysctl_header->ctl_table_arg;
unregister_net_sysctl_table(net->ct.helper_sysctl_header);
kfree(table);
}
#else
static int nf_conntrack_helper_init_sysctl(struct net *net)
{
return 0;
}
static void nf_conntrack_helper_fini_sysctl(struct net *net)
{
}
#endif /* CONFIG_SYSCTL */
/* Stupid hash, but collision free for the default registrations of the /* Stupid hash, but collision free for the default registrations of the
* helpers currently in the kernel. */ * helpers currently in the kernel. */
...@@ -118,17 +179,38 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl, ...@@ -118,17 +179,38 @@ int __nf_ct_try_assign_helper(struct nf_conn *ct, struct nf_conn *tmpl,
{ {
struct nf_conntrack_helper *helper = NULL; struct nf_conntrack_helper *helper = NULL;
struct nf_conn_help *help; struct nf_conn_help *help;
struct net *net = nf_ct_net(ct);
int ret = 0; int ret = 0;
/* We already got a helper explicitly attached. The function
* nf_conntrack_alter_reply - in case NAT is in use - asks for looking
* the helper up again. Since now the user is in full control of
* making consistent helper configurations, skip this automatic
* re-lookup, otherwise we'll lose the helper.
*/
if (test_bit(IPS_HELPER_BIT, &ct->status))
return 0;
if (tmpl != NULL) { if (tmpl != NULL) {
help = nfct_help(tmpl); help = nfct_help(tmpl);
if (help != NULL) if (help != NULL) {
helper = help->helper; helper = help->helper;
set_bit(IPS_HELPER_BIT, &ct->status);
}
} }
help = nfct_help(ct); help = nfct_help(ct);
if (helper == NULL) if (net->ct.sysctl_auto_assign_helper && helper == NULL) {
helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple); helper = __nf_ct_helper_find(&ct->tuplehash[IP_CT_DIR_REPLY].tuple);
if (unlikely(!net->ct.auto_assign_helper_warned && helper)) {
pr_info("nf_conntrack: automatic helper "
"assignment is deprecated and it will "
"be removed soon. Use the iptables CT target "
"to attach helpers instead.\n");
net->ct.auto_assign_helper_warned = true;
}
}
if (helper == NULL) { if (helper == NULL) {
if (help) if (help)
RCU_INIT_POINTER(help->helper, NULL); RCU_INIT_POINTER(help->helper, NULL);
...@@ -315,28 +397,44 @@ static struct nf_ct_ext_type helper_extend __read_mostly = { ...@@ -315,28 +397,44 @@ static struct nf_ct_ext_type helper_extend __read_mostly = {
.id = NF_CT_EXT_HELPER, .id = NF_CT_EXT_HELPER,
}; };
int nf_conntrack_helper_init(void) int nf_conntrack_helper_init(struct net *net)
{ {
int err; int err;
nf_ct_helper_hsize = 1; /* gets rounded up to use one page */ net->ct.auto_assign_helper_warned = false;
nf_ct_helper_hash = nf_ct_alloc_hashtable(&nf_ct_helper_hsize, 0); net->ct.sysctl_auto_assign_helper = nf_ct_auto_assign_helper;
if (!nf_ct_helper_hash)
return -ENOMEM; if (net_eq(net, &init_net)) {
nf_ct_helper_hsize = 1; /* gets rounded up to use one page */
nf_ct_helper_hash =
nf_ct_alloc_hashtable(&nf_ct_helper_hsize, 0);
if (!nf_ct_helper_hash)
return -ENOMEM;
err = nf_ct_extend_register(&helper_extend); err = nf_ct_extend_register(&helper_extend);
if (err < 0)
goto err1;
}
err = nf_conntrack_helper_init_sysctl(net);
if (err < 0) if (err < 0)
goto err1; goto out_sysctl;
return 0; return 0;
out_sysctl:
if (net_eq(net, &init_net))
nf_ct_extend_unregister(&helper_extend);
err1: err1:
nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize); nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
return err; return err;
} }
void nf_conntrack_helper_fini(void) void nf_conntrack_helper_fini(struct net *net)
{ {
nf_ct_extend_unregister(&helper_extend); nf_conntrack_helper_fini_sysctl(net);
nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize); if (net_eq(net, &init_net)) {
nf_ct_extend_unregister(&helper_extend);
nf_ct_free_hashtable(nf_ct_helper_hash, nf_ct_helper_hsize);
}
} }
...@@ -2080,7 +2080,15 @@ static int ...@@ -2080,7 +2080,15 @@ static int
ctnetlink_change_expect(struct nf_conntrack_expect *x, ctnetlink_change_expect(struct nf_conntrack_expect *x,
const struct nlattr * const cda[]) const struct nlattr * const cda[])
{ {
return -EOPNOTSUPP; if (cda[CTA_EXPECT_TIMEOUT]) {
if (!del_timer(&x->timeout))
return -ETIME;
x->timeout.expires = jiffies +
ntohl(nla_get_be32(cda[CTA_EXPECT_TIMEOUT])) * HZ;
add_timer(&x->timeout);
}
return 0;
} }
static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = { static const struct nla_policy exp_nat_nla_policy[CTA_EXPECT_NAT_MAX+1] = {
......
...@@ -14,7 +14,6 @@ ...@@ -14,7 +14,6 @@
#include <linux/netlink.h> #include <linux/netlink.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/if.h> #include <linux/if.h>
#include <linux/netfilter_ipv4/ip_queue.h>
#include <linux/inet_diag.h> #include <linux/inet_diag.h>
#include <linux/xfrm.h> #include <linux/xfrm.h>
#include <linux/audit.h> #include <linux/audit.h>
...@@ -70,12 +69,6 @@ static struct nlmsg_perm nlmsg_route_perms[] = ...@@ -70,12 +69,6 @@ static struct nlmsg_perm nlmsg_route_perms[] =
{ RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE }, { RTM_SETDCB, NETLINK_ROUTE_SOCKET__NLMSG_WRITE },
}; };
static struct nlmsg_perm nlmsg_firewall_perms[] =
{
{ IPQM_MODE, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE },
{ IPQM_VERDICT, NETLINK_FIREWALL_SOCKET__NLMSG_WRITE },
};
static struct nlmsg_perm nlmsg_tcpdiag_perms[] = static struct nlmsg_perm nlmsg_tcpdiag_perms[] =
{ {
{ TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ }, { TCPDIAG_GETSOCK, NETLINK_TCPDIAG_SOCKET__NLMSG_READ },
...@@ -145,12 +138,6 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm) ...@@ -145,12 +138,6 @@ int selinux_nlmsg_lookup(u16 sclass, u16 nlmsg_type, u32 *perm)
sizeof(nlmsg_route_perms)); sizeof(nlmsg_route_perms));
break; break;
case SECCLASS_NETLINK_FIREWALL_SOCKET:
case SECCLASS_NETLINK_IP6FW_SOCKET:
err = nlmsg_perm(nlmsg_type, perm, nlmsg_firewall_perms,
sizeof(nlmsg_firewall_perms));
break;
case SECCLASS_NETLINK_TCPDIAG_SOCKET: case SECCLASS_NETLINK_TCPDIAG_SOCKET:
err = nlmsg_perm(nlmsg_type, perm, nlmsg_tcpdiag_perms, err = nlmsg_perm(nlmsg_type, perm, nlmsg_tcpdiag_perms,
sizeof(nlmsg_tcpdiag_perms)); sizeof(nlmsg_tcpdiag_perms));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment