aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/net/ip_vs.h20
-rw-r--r--include/net/netns/ip_vs.h3
-rw-r--r--net/netfilter/ipvs/ip_vs_proto.c66
3 files changed, 88 insertions, 1 deletions
diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
index d551e0d8fd9a..88d4e40b538a 100644
--- a/include/net/ip_vs.h
+++ b/include/net/ip_vs.h
@@ -352,6 +352,7 @@ struct iphdr;
352struct ip_vs_conn; 352struct ip_vs_conn;
353struct ip_vs_app; 353struct ip_vs_app;
354struct sk_buff; 354struct sk_buff;
355struct ip_vs_proto_data;
355 356
356struct ip_vs_protocol { 357struct ip_vs_protocol {
357 struct ip_vs_protocol *next; 358 struct ip_vs_protocol *next;
@@ -366,6 +367,10 @@ struct ip_vs_protocol {
366 367
367 void (*exit)(struct ip_vs_protocol *pp); 368 void (*exit)(struct ip_vs_protocol *pp);
368 369
370 void (*init_netns)(struct net *net, struct ip_vs_proto_data *pd);
371
372 void (*exit_netns)(struct net *net, struct ip_vs_proto_data *pd);
373
369 int (*conn_schedule)(int af, struct sk_buff *skb, 374 int (*conn_schedule)(int af, struct sk_buff *skb,
370 struct ip_vs_protocol *pp, 375 struct ip_vs_protocol *pp,
371 int *verdict, struct ip_vs_conn **cpp); 376 int *verdict, struct ip_vs_conn **cpp);
@@ -417,7 +422,20 @@ struct ip_vs_protocol {
417 int (*set_state_timeout)(struct ip_vs_protocol *pp, char *sname, int to); 422 int (*set_state_timeout)(struct ip_vs_protocol *pp, char *sname, int to);
418}; 423};
419 424
420extern struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto); 425/*
426 * protocol data per netns
427 */
428struct ip_vs_proto_data {
429 struct ip_vs_proto_data *next;
430 struct ip_vs_protocol *pp;
431 int *timeout_table; /* protocol timeout table */
432 atomic_t appcnt; /* counter of proto app incs. */
433 struct tcp_states_t *tcp_state_table;
434};
435
436extern struct ip_vs_protocol *ip_vs_proto_get(unsigned short proto);
437extern struct ip_vs_proto_data *ip_vs_proto_data_get(struct net *net,
438 unsigned short proto);
421 439
422struct ip_vs_conn_param { 440struct ip_vs_conn_param {
423 const union nf_inet_addr *caddr; 441 const union nf_inet_addr *caddr;
diff --git a/include/net/netns/ip_vs.h b/include/net/netns/ip_vs.h
index d14581cc4fe0..6f4e089b8db2 100644
--- a/include/net/netns/ip_vs.h
+++ b/include/net/netns/ip_vs.h
@@ -28,6 +28,9 @@ struct netns_ipvs {
28 #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1) 28 #define IP_VS_RTAB_MASK (IP_VS_RTAB_SIZE - 1)
29 29
30 struct list_head rs_table[IP_VS_RTAB_SIZE]; 30 struct list_head rs_table[IP_VS_RTAB_SIZE];
31 /* ip_vs_proto */
32 #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */
33 struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE];
31 34
32 /* ip_vs_lblc */ 35 /* ip_vs_lblc */
33 int sysctl_lblc_expiration; 36 int sysctl_lblc_expiration;
diff --git a/net/netfilter/ipvs/ip_vs_proto.c b/net/netfilter/ipvs/ip_vs_proto.c
index 45392942d0e7..576e29648c53 100644
--- a/net/netfilter/ipvs/ip_vs_proto.c
+++ b/net/netfilter/ipvs/ip_vs_proto.c
@@ -60,6 +60,31 @@ static int __used __init register_ip_vs_protocol(struct ip_vs_protocol *pp)
60 return 0; 60 return 0;
61} 61}
62 62
63/*
64 * register an ipvs protocols netns related data
65 */
66static int
67register_ip_vs_proto_netns(struct net *net, struct ip_vs_protocol *pp)
68{
69 struct netns_ipvs *ipvs = net_ipvs(net);
70 unsigned hash = IP_VS_PROTO_HASH(pp->protocol);
71 struct ip_vs_proto_data *pd =
72 kzalloc(sizeof(struct ip_vs_proto_data), GFP_ATOMIC);
73
74 if (!pd) {
75 pr_err("%s(): no memory.\n", __func__);
76 return -ENOMEM;
77 }
78 pd->pp = pp; /* For speed issues */
79 pd->next = ipvs->proto_data_table[hash];
80 ipvs->proto_data_table[hash] = pd;
81 atomic_set(&pd->appcnt, 0); /* Init app counter */
82
83 if (pp->init_netns != NULL)
84 pp->init_netns(net, pd);
85
86 return 0;
87}
63 88
64/* 89/*
65 * unregister an ipvs protocol 90 * unregister an ipvs protocol
@@ -82,6 +107,29 @@ static int unregister_ip_vs_protocol(struct ip_vs_protocol *pp)
82 return -ESRCH; 107 return -ESRCH;
83} 108}
84 109
110/*
111 * unregister an ipvs protocols netns data
112 */
113static int
114unregister_ip_vs_proto_netns(struct net *net, struct ip_vs_proto_data *pd)
115{
116 struct netns_ipvs *ipvs = net_ipvs(net);
117 struct ip_vs_proto_data **pd_p;
118 unsigned hash = IP_VS_PROTO_HASH(pd->pp->protocol);
119
120 pd_p = &ipvs->proto_data_table[hash];
121 for (; *pd_p; pd_p = &(*pd_p)->next) {
122 if (*pd_p == pd) {
123 *pd_p = pd->next;
124 if (pd->pp->exit_netns != NULL)
125 pd->pp->exit_netns(net, pd);
126 kfree(pd);
127 return 0;
128 }
129 }
130
131 return -ESRCH;
132}
85 133
86/* 134/*
87 * get ip_vs_protocol object by its proto. 135 * get ip_vs_protocol object by its proto.
@@ -100,6 +148,24 @@ struct ip_vs_protocol * ip_vs_proto_get(unsigned short proto)
100} 148}
101EXPORT_SYMBOL(ip_vs_proto_get); 149EXPORT_SYMBOL(ip_vs_proto_get);
102 150
151/*
152 * get ip_vs_protocol object data by netns and proto
153 */
154struct ip_vs_proto_data *
155ip_vs_proto_data_get(struct net *net, unsigned short proto)
156{
157 struct netns_ipvs *ipvs = net_ipvs(net);
158 struct ip_vs_proto_data *pd;
159 unsigned hash = IP_VS_PROTO_HASH(proto);
160
161 for (pd = ipvs->proto_data_table[hash]; pd; pd = pd->next) {
162 if (pd->pp->protocol == proto)
163 return pd;
164 }
165
166 return NULL;
167}
168EXPORT_SYMBOL(ip_vs_proto_data_get);
103 169
104/* 170/*
105 * Propagate event for state change to all protocols 171 * Propagate event for state change to all protocols