diff options
-rw-r--r-- | net/netfilter/ipvs/ip_vs_sync.c | 154 |
1 files changed, 142 insertions, 12 deletions
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c index 47eed672dc08..566482f227fa 100644 --- a/net/netfilter/ipvs/ip_vs_sync.c +++ b/net/netfilter/ipvs/ip_vs_sync.c | |||
@@ -43,11 +43,13 @@ | |||
43 | #define IP_VS_SYNC_GROUP 0xe0000051 /* multicast addr - 224.0.0.81 */ | 43 | #define IP_VS_SYNC_GROUP 0xe0000051 /* multicast addr - 224.0.0.81 */ |
44 | #define IP_VS_SYNC_PORT 8848 /* multicast port */ | 44 | #define IP_VS_SYNC_PORT 8848 /* multicast port */ |
45 | 45 | ||
46 | #define SYNC_PROTO_VER 1 /* Protocol version in header */ | ||
46 | 47 | ||
47 | /* | 48 | /* |
48 | * IPVS sync connection entry | 49 | * IPVS sync connection entry |
50 | * Version 0, i.e. original version. | ||
49 | */ | 51 | */ |
50 | struct ip_vs_sync_conn { | 52 | struct ip_vs_sync_conn_v0 { |
51 | __u8 reserved; | 53 | __u8 reserved; |
52 | 54 | ||
53 | /* Protocol, addresses and port numbers */ | 55 | /* Protocol, addresses and port numbers */ |
@@ -71,40 +73,157 @@ struct ip_vs_sync_conn_options { | |||
71 | struct ip_vs_seq out_seq; /* outgoing seq. struct */ | 73 | struct ip_vs_seq out_seq; /* outgoing seq. struct */ |
72 | }; | 74 | }; |
73 | 75 | ||
76 | /* | ||
77 | Sync Connection format (sync_conn) | ||
78 | |||
79 | 0 1 2 3 | ||
80 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
81 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
82 | | Type | Protocol | Ver. | Size | | ||
83 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
84 | | Flags | | ||
85 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
86 | | State | cport | | ||
87 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
88 | | vport | dport | | ||
89 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
90 | | fwmark | | ||
91 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
92 | | timeout (in sec.) | | ||
93 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
94 | | ... | | ||
95 | | IP-Addresses (v4 or v6) | | ||
96 | | ... | | ||
97 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
98 | Optional Parameters. | ||
99 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
100 | | Param. Type | Param. Length | Param. data | | ||
101 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | | ||
102 | | ... | | ||
103 | | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
104 | | | Param Type | Param. Length | | ||
105 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
106 | | Param data | | ||
107 | | Last Param data should be padded for 32 bit alignment | | ||
108 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
109 | */ | ||
110 | |||
111 | /* | ||
112 | * Type 0, IPv4 sync connection format | ||
113 | */ | ||
114 | struct ip_vs_sync_v4 { | ||
115 | __u8 type; | ||
116 | __u8 protocol; /* Which protocol (TCP/UDP) */ | ||
117 | __be16 ver_size; /* Version msb 4 bits */ | ||
118 | /* Flags and state transition */ | ||
119 | __be32 flags; /* status flags */ | ||
120 | __be16 state; /* state info */ | ||
121 | /* Protocol, addresses and port numbers */ | ||
122 | __be16 cport; | ||
123 | __be16 vport; | ||
124 | __be16 dport; | ||
125 | __be32 fwmark; /* Firewall mark from skb */ | ||
126 | __be32 timeout; /* cp timeout */ | ||
127 | __be32 caddr; /* client address */ | ||
128 | __be32 vaddr; /* virtual address */ | ||
129 | __be32 daddr; /* destination address */ | ||
130 | /* The sequence options start here */ | ||
131 | /* PE data padded to 32bit alignment after seq. options */ | ||
132 | }; | ||
133 | /* | ||
134 | * Type 2 messages IPv6 | ||
135 | */ | ||
136 | struct ip_vs_sync_v6 { | ||
137 | __u8 type; | ||
138 | __u8 protocol; /* Which protocol (TCP/UDP) */ | ||
139 | __be16 ver_size; /* Version msb 4 bits */ | ||
140 | /* Flags and state transition */ | ||
141 | __be32 flags; /* status flags */ | ||
142 | __be16 state; /* state info */ | ||
143 | /* Protocol, addresses and port numbers */ | ||
144 | __be16 cport; | ||
145 | __be16 vport; | ||
146 | __be16 dport; | ||
147 | __be32 fwmark; /* Firewall mark from skb */ | ||
148 | __be32 timeout; /* cp timeout */ | ||
149 | struct in6_addr caddr; /* client address */ | ||
150 | struct in6_addr vaddr; /* virtual address */ | ||
151 | struct in6_addr daddr; /* destination address */ | ||
152 | /* The sequence options start here */ | ||
153 | /* PE data padded to 32bit alignment after seq. options */ | ||
154 | }; | ||
155 | |||
156 | union ip_vs_sync_conn { | ||
157 | struct ip_vs_sync_v4 v4; | ||
158 | struct ip_vs_sync_v6 v6; | ||
159 | }; | ||
160 | |||
161 | /* Bits in Type field in above */ | ||
162 | #define STYPE_INET6 0 | ||
163 | #define STYPE_F_INET6 (1 << STYPE_INET6) | ||
164 | |||
165 | #define SVER_SHIFT 12 /* Shift to get version */ | ||
166 | #define SVER_MASK 0x0fff /* Mask to strip version */ | ||
167 | |||
168 | #define IPVS_OPT_SEQ_DATA 1 | ||
169 | #define IPVS_OPT_PE_DATA 2 | ||
170 | #define IPVS_OPT_PE_NAME 3 | ||
171 | #define IPVS_OPT_PARAM 7 | ||
172 | |||
173 | #define IPVS_OPT_F_SEQ_DATA (1 << (IPVS_OPT_SEQ_DATA-1)) | ||
174 | #define IPVS_OPT_F_PE_DATA (1 << (IPVS_OPT_PE_DATA-1)) | ||
175 | #define IPVS_OPT_F_PE_NAME (1 << (IPVS_OPT_PE_NAME-1)) | ||
176 | #define IPVS_OPT_F_PARAM (1 << (IPVS_OPT_PARAM-1)) | ||
177 | |||
74 | struct ip_vs_sync_thread_data { | 178 | struct ip_vs_sync_thread_data { |
75 | struct socket *sock; | 179 | struct socket *sock; |
76 | char *buf; | 180 | char *buf; |
77 | }; | 181 | }; |
78 | 182 | ||
79 | #define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn)) | 183 | /* Version 0 definition of packet sizes */ |
184 | #define SIMPLE_CONN_SIZE (sizeof(struct ip_vs_sync_conn_v0)) | ||
80 | #define FULL_CONN_SIZE \ | 185 | #define FULL_CONN_SIZE \ |
81 | (sizeof(struct ip_vs_sync_conn) + sizeof(struct ip_vs_sync_conn_options)) | 186 | (sizeof(struct ip_vs_sync_conn_v0) + sizeof(struct ip_vs_sync_conn_options)) |
82 | 187 | ||
83 | 188 | ||
84 | /* | 189 | /* |
85 | The master mulitcasts messages to the backup load balancers in the | 190 | The master mulitcasts messages (Datagrams) to the backup load balancers |
86 | following format. | 191 | in the following format. |
192 | |||
193 | Version 1: | ||
194 | Note, first byte should be Zero, so ver 0 receivers will drop the packet. | ||
87 | 195 | ||
88 | 0 1 2 3 | 196 | 0 1 2 3 |
89 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | 197 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 |
90 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 198 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
91 | | Count Conns | SyncID | Size | | 199 | | 0 | SyncID | Size | |
200 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
201 | | Count Conns | Version | Reserved, set to Zero | | ||
92 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 202 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
93 | | | | 203 | | | |
94 | | IPVS Sync Connection (1) | | 204 | | IPVS Sync Connection (1) | |
95 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 205 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
96 | | . | | 206 | | . | |
97 | | . | | 207 | ~ . ~ |
98 | | . | | 208 | | . | |
99 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 209 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
100 | | | | 210 | | | |
101 | | IPVS Sync Connection (n) | | 211 | | IPVS Sync Connection (n) | |
102 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | 212 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
213 | |||
214 | Version 0 Header | ||
215 | 0 1 2 3 | ||
216 | 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 | ||
217 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
218 | | Count Conns | SyncID | Size | | ||
219 | +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | ||
220 | | IPVS Sync Connection (1) | | ||
103 | */ | 221 | */ |
104 | 222 | ||
105 | #define SYNC_MESG_HEADER_LEN 4 | 223 | #define SYNC_MESG_HEADER_LEN 4 |
106 | #define MAX_CONNS_PER_SYNCBUFF 255 /* nr_conns in ip_vs_sync_mesg is 8 bit */ | 224 | #define MAX_CONNS_PER_SYNCBUFF 255 /* nr_conns in ip_vs_sync_mesg is 8 bit */ |
107 | 225 | ||
226 | /* Version 0 header */ | ||
108 | struct ip_vs_sync_mesg { | 227 | struct ip_vs_sync_mesg { |
109 | __u8 nr_conns; | 228 | __u8 nr_conns; |
110 | __u8 syncid; | 229 | __u8 syncid; |
@@ -113,6 +232,17 @@ struct ip_vs_sync_mesg { | |||
113 | /* ip_vs_sync_conn entries start here */ | 232 | /* ip_vs_sync_conn entries start here */ |
114 | }; | 233 | }; |
115 | 234 | ||
235 | /* Version 1 header */ | ||
236 | struct ip_vs_sync_mesg_v2 { | ||
237 | __u8 reserved; /* must be zero */ | ||
238 | __u8 syncid; | ||
239 | __u16 size; | ||
240 | __u8 nr_conns; | ||
241 | __s8 version; /* SYNC_PROTO_VER */ | ||
242 | __u16 spare; | ||
243 | /* ip_vs_sync_conn entries start here */ | ||
244 | }; | ||
245 | |||
116 | /* the maximum length of sync (sending/receiving) message */ | 246 | /* the maximum length of sync (sending/receiving) message */ |
117 | static int sync_send_mesg_maxlen; | 247 | static int sync_send_mesg_maxlen; |
118 | static int sync_recv_mesg_maxlen; | 248 | static int sync_recv_mesg_maxlen; |
@@ -239,7 +369,7 @@ get_curr_sync_buff(unsigned long time) | |||
239 | void ip_vs_sync_conn(const struct ip_vs_conn *cp) | 369 | void ip_vs_sync_conn(const struct ip_vs_conn *cp) |
240 | { | 370 | { |
241 | struct ip_vs_sync_mesg *m; | 371 | struct ip_vs_sync_mesg *m; |
242 | struct ip_vs_sync_conn *s; | 372 | struct ip_vs_sync_conn_v0 *s; |
243 | int len; | 373 | int len; |
244 | 374 | ||
245 | spin_lock(&curr_sb_lock); | 375 | spin_lock(&curr_sb_lock); |
@@ -254,7 +384,7 @@ void ip_vs_sync_conn(const struct ip_vs_conn *cp) | |||
254 | len = (cp->flags & IP_VS_CONN_F_SEQ_MASK) ? FULL_CONN_SIZE : | 384 | len = (cp->flags & IP_VS_CONN_F_SEQ_MASK) ? FULL_CONN_SIZE : |
255 | SIMPLE_CONN_SIZE; | 385 | SIMPLE_CONN_SIZE; |
256 | m = curr_sb->mesg; | 386 | m = curr_sb->mesg; |
257 | s = (struct ip_vs_sync_conn *)curr_sb->head; | 387 | s = (struct ip_vs_sync_conn_v0 *)curr_sb->head; |
258 | 388 | ||
259 | /* copy members */ | 389 | /* copy members */ |
260 | s->protocol = cp->protocol; | 390 | s->protocol = cp->protocol; |
@@ -306,7 +436,7 @@ ip_vs_conn_fill_param_sync(int af, int protocol, | |||
306 | static void ip_vs_process_message(char *buffer, const size_t buflen) | 436 | static void ip_vs_process_message(char *buffer, const size_t buflen) |
307 | { | 437 | { |
308 | struct ip_vs_sync_mesg *m = (struct ip_vs_sync_mesg *)buffer; | 438 | struct ip_vs_sync_mesg *m = (struct ip_vs_sync_mesg *)buffer; |
309 | struct ip_vs_sync_conn *s; | 439 | struct ip_vs_sync_conn_v0 *s; |
310 | struct ip_vs_sync_conn_options *opt; | 440 | struct ip_vs_sync_conn_options *opt; |
311 | struct ip_vs_conn *cp; | 441 | struct ip_vs_conn *cp; |
312 | struct ip_vs_protocol *pp; | 442 | struct ip_vs_protocol *pp; |
@@ -343,7 +473,7 @@ static void ip_vs_process_message(char *buffer, const size_t buflen) | |||
343 | IP_VS_ERR_RL("bogus conn in sync message\n"); | 473 | IP_VS_ERR_RL("bogus conn in sync message\n"); |
344 | return; | 474 | return; |
345 | } | 475 | } |
346 | s = (struct ip_vs_sync_conn *) p; | 476 | s = (struct ip_vs_sync_conn_v0 *) p; |
347 | flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC; | 477 | flags = ntohs(s->flags) | IP_VS_CONN_F_SYNC; |
348 | flags &= ~IP_VS_CONN_F_HASHED; | 478 | flags &= ~IP_VS_CONN_F_HASHED; |
349 | if (flags & IP_VS_CONN_F_SEQ_MASK) { | 479 | if (flags & IP_VS_CONN_F_SEQ_MASK) { |
@@ -849,7 +979,7 @@ int start_sync_thread(int state, char *mcast_ifn, __u8 syncid) | |||
849 | 979 | ||
850 | IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current)); | 980 | IP_VS_DBG(7, "%s(): pid %d\n", __func__, task_pid_nr(current)); |
851 | IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n", | 981 | IP_VS_DBG(7, "Each ip_vs_sync_conn entry needs %Zd bytes\n", |
852 | sizeof(struct ip_vs_sync_conn)); | 982 | sizeof(struct ip_vs_sync_conn_v0)); |
853 | 983 | ||
854 | if (state == IP_VS_STATE_MASTER) { | 984 | if (state == IP_VS_STATE_MASTER) { |
855 | if (sync_master_thread) | 985 | if (sync_master_thread) |