Add a IP_VS_F_NET_INIT_OK flag
that other modules can use for check of a successful init of ip_vs
Signed-off-by: Hans Schillstrom <hans.schillstrom@xxxxxxxxxxxx>
---
include/net/ip_vs.h | 20 +++++++++++++++++++-
net/netfilter/ipvs/ip_vs_conn.c | 2 +-
net/netfilter/ipvs/ip_vs_core.c | 15 +++++++++------
net/netfilter/ipvs/ip_vs_ctl.c | 2 +-
net/netfilter/ipvs/ip_vs_ftp.c | 2 ++
net/netfilter/ipvs/ip_vs_lblc.c | 3 +++
net/netfilter/ipvs/ip_vs_lblcr.c | 3 +++
7 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index 04e2211..96add20 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -787,7 +787,8 @@ struct ip_vs_app {
/* IPVS in network namespace */
struct netns_ipvs {
int gen; /* Generation */
- int enable; /* enable like nf_hooks do */
+ /* Status flags: enable like nf_hooks, and netns init ok */
+ int status;
/*
* Hash table: for real service lookups
*/
@@ -909,6 +910,23 @@ struct netns_ipvs {
struct net *net; /* Needed by timer routines */
};
+/*
+ * Status flags for each netns
+ */
+enum {
+ IP_VS_ENABLE, /* Enabled ipvs i.e. service registered */
+ IP_VS_NET_INIT_OK, /* Netns init is OK */
+ IP_VS_F_ENABLE = (1 << IP_VS_ENABLE),
+ IP_VS_F_NET_INIT_OK = (1 << IP_VS_NET_INIT_OK)
+};
+
+#define IS_IPVS_ENABLED(ipvs) (ipvs->status & IP_VS_F_ENABLE)
+#define IPVS_ENABLE(ipvs) (ipvs->status |= IP_VS_F_ENABLE)
+#define IPVS_DISABLE(ipvs) (ipvs->status &= ~IP_VS_F_ENABLE)
+
+#define IS_IPVS_NETNS_OK(ipvs) (ipvs->status & IP_VS_F_NET_INIT_OK)
+#define IPVS_NETNS_OK(ipvs) (ipvs->status |= IP_VS_F_NET_INIT_OK)
+
#define DEFAULT_SYNC_THRESHOLD 3
#define DEFAULT_SYNC_PERIOD 50
#define DEFAULT_SYNC_VER 1
diff --git a/net/netfilter/ipvs/ip_vs_conn.c b/net/netfilter/ipvs/ip_vs_conn.c
index 4a09b78..4f2a7ec 100644
--- a/net/netfilter/ipvs/ip_vs_conn.c
+++ b/net/netfilter/ipvs/ip_vs_conn.c
@@ -783,7 +783,7 @@ static void ip_vs_conn_expire(unsigned long data)
* conntrack cleanup for the net.
*/
smp_rmb();
- if (ipvs->enable)
+ if (IS_IPVS_ENABLED(ipvs))
ip_vs_conn_drop_conntrack(cp);
}
diff --git a/net/netfilter/ipvs/ip_vs_core.c b/net/netfilter/ipvs/ip_vs_core.c
index b5a5c73..58722a2 100644
--- a/net/netfilter/ipvs/ip_vs_core.c
+++ b/net/netfilter/ipvs/ip_vs_core.c
@@ -1112,7 +1112,7 @@ ip_vs_out(unsigned int hooknum, struct sk_buff *skb, int
af)
return NF_ACCEPT;
net = skb_net(skb);
- if (!net_ipvs(net)->enable)
+ if (!IS_IPVS_ENABLED(net_ipvs(net)))
return NF_ACCEPT;
ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
@@ -1513,7 +1513,7 @@ ip_vs_in(unsigned int hooknum, struct sk_buff *skb, int
af)
}
/* ipvs enabled in this netns ? */
net = skb_net(skb);
- if (!net_ipvs(net)->enable)
+ if (!IS_IPVS_ENABLED(net_ipvs(net)))
return NF_ACCEPT;
ip_vs_fill_iphdr(af, skb_network_header(skb), &iph);
@@ -1735,7 +1735,7 @@ ip_vs_forward_icmp(unsigned int hooknum, struct sk_buff
*skb,
/* ipvs enabled in this netns ? */
net = skb_net(skb);
- if (!net_ipvs(net)->enable)
+ if (!IS_IPVS_ENABLED(net_ipvs(net)))
return NF_ACCEPT;
return ip_vs_in_icmp(skb, &r, hooknum);
@@ -1755,7 +1755,7 @@ ip_vs_forward_icmp_v6(unsigned int hooknum, struct
sk_buff *skb,
/* ipvs enabled in this netns ? */
net = skb_net(skb);
- if (!net_ipvs(net)->enable)
+ if (!IS_IPVS_ENABLED(net_ipvs(net)))
return NF_ACCEPT;
return ip_vs_in_icmp_v6(skb, &r, hooknum);
@@ -1881,7 +1881,7 @@ static int __net_init __ip_vs_init(struct net *net)
return -ENOMEM;
/* Hold the beast until a service is registerd */
- ipvs->enable = 0;
+ ipvs->status = 0;
ipvs->net = net;
/* Counters used for creating unique names */
ipvs->gen = atomic_read(&ipvs_netns_cnt);
@@ -1906,6 +1906,7 @@ static int __net_init __ip_vs_init(struct net *net)
if (ip_vs_sync_net_init(net) < 0)
goto sync_fail;
+ IPVS_NETNS_OK(ipvs);
printk(KERN_INFO "IPVS: Creating netns size=%zu id=%d\n",
sizeof(struct netns_ipvs), ipvs->gen);
return 0;
@@ -1924,6 +1925,7 @@ protocol_fail:
control_fail:
ip_vs_estimator_net_cleanup(net);
estimator_fail:
+ ipvs->status = 0; /* Nothing is enabled */
return -ENOMEM;
}
@@ -1936,12 +1938,13 @@ static void __net_exit __ip_vs_cleanup(struct net *net)
ip_vs_control_net_cleanup(net);
ip_vs_estimator_net_cleanup(net);
IP_VS_DBG(2, "ipvs netns %d released\n", net_ipvs(net)->gen);
+ net->ipvs = NULL;
}
static void __net_exit __ip_vs_dev_cleanup(struct net *net)
{
EnterFunction(2);
- net_ipvs(net)->enable = 0; /* Disable packet reception */
+ IPVS_DISABLE(net_ipvs(net)); /* Disable packet reception */
smp_wmb();
ip_vs_sync_net_cleanup(net);
LeaveFunction(2);
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index b8d0df7..5392de9 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -1221,7 +1221,7 @@ ip_vs_add_service(struct net *net, struct
ip_vs_service_user_kern *u,
*svc_p = svc;
/* Now there is a service - full throttle */
- ipvs->enable = 1;
+ IPVS_ENABLE(ipvs);
return 0;
diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
index debb8c7..6bc2420 100644
--- a/net/netfilter/ipvs/ip_vs_ftp.c
+++ b/net/netfilter/ipvs/ip_vs_ftp.c
@@ -439,6 +439,8 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
struct ip_vs_app *app;
struct netns_ipvs *ipvs = net_ipvs(net);
+ if (!IS_IPVS_NETNS_OK(ipvs))
+ return -EUNATCH;
app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
if (!app)
return -ENOMEM;
diff --git a/net/netfilter/ipvs/ip_vs_lblc.c b/net/netfilter/ipvs/ip_vs_lblc.c
index 27c24f1..f158f0c 100644
--- a/net/netfilter/ipvs/ip_vs_lblc.c
+++ b/net/netfilter/ipvs/ip_vs_lblc.c
@@ -551,6 +551,9 @@ static int __net_init __ip_vs_lblc_init(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
+ if (!IS_IPVS_NETNS_OK(ipvs))
+ return -EUNATCH;
+
if (!net_eq(net, &init_net)) {
ipvs->lblc_ctl_table = kmemdup(vs_vars_table,
sizeof(vs_vars_table),
diff --git a/net/netfilter/ipvs/ip_vs_lblcr.c b/net/netfilter/ipvs/ip_vs_lblcr.c
index 7498756..aeecda4 100644
--- a/net/netfilter/ipvs/ip_vs_lblcr.c
+++ b/net/netfilter/ipvs/ip_vs_lblcr.c
@@ -745,6 +745,9 @@ static int __net_init __ip_vs_lblcr_init(struct net *net)
{
struct netns_ipvs *ipvs = net_ipvs(net);
+ if (!IS_IPVS_NETNS_OK(ipvs))
+ return -EUNATCH;
+
if (!net_eq(net, &init_net)) {
ipvs->lblcr_ctl_table = kmemdup(vs_vars_table,
sizeof(vs_vars_table),
--
1.7.2.3
--
To unsubscribe from this list: send the line "unsubscribe lvs-devel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
|