24
24
25
25
VLOG_DEFINE_THIS_MODULE (lb );
26
26
27
- static void ovn_lb_backends_clear (struct ovn_lb_vip * vip );
27
+ static bool
28
+ ovn_lb_backend_init_explicit (const struct ovn_lb_vip * lb_vip ,
29
+ struct ovn_lb_backend * backend ,
30
+ const char * token , struct ds * errors )
31
+ {
32
+ int backend_addr_family ;
33
+ if (!ip_address_and_port_from_lb_key (token , & backend -> ip_str ,
34
+ & backend -> ip , & backend -> port ,
35
+ & backend_addr_family )) {
36
+ if (lb_vip -> port_str ) {
37
+ ds_put_format (errors , "%s: should be an IP address and a "
38
+ "port number with : as a separator, " ,
39
+ token );
40
+ } else {
41
+ ds_put_format (errors , "%s: should be an IP address, " , token );
42
+ }
43
+ return false;
44
+ }
45
+
46
+ if (lb_vip -> address_family != backend_addr_family ) {
47
+ free (backend -> ip_str );
48
+ ds_put_format (errors , "%s: IP address family is different from "
49
+ "VIP %s, " ,
50
+ token , lb_vip -> vip_str );
51
+ return false;
52
+ }
53
+
54
+ if (lb_vip -> port_str ) {
55
+ if (!backend -> port ) {
56
+ free (backend -> ip_str );
57
+ ds_put_format (errors , "%s: should be an IP address and "
58
+ "a port number with : as a separator, " ,
59
+ token );
60
+ return false;
61
+ }
62
+ } else {
63
+ if (backend -> port ) {
64
+ free (backend -> ip_str );
65
+ ds_put_format (errors , "%s: should be an IP address, " , token );
66
+ return false;
67
+ }
68
+ }
69
+
70
+ backend -> port_str =
71
+ backend -> port ? xasprintf ("%" PRIu16 , backend -> port ) : NULL ;
72
+ return true;
73
+ }
28
74
29
75
/* Format for backend ips: "IP1:port1,IP2:port2,...". */
30
76
static char *
@@ -47,46 +93,10 @@ ovn_lb_backends_init_explicit(struct ovn_lb_vip *lb_vip, const char *value)
47
93
}
48
94
49
95
struct ovn_lb_backend * backend = & lb_vip -> backends [lb_vip -> n_backends ];
50
- int backend_addr_family ;
51
- if (!ip_address_and_port_from_lb_key (token , & backend -> ip_str ,
52
- & backend -> ip , & backend -> port ,
53
- & backend_addr_family )) {
54
- if (lb_vip -> port_str ) {
55
- ds_put_format (& errors , "%s: should be an IP address and a "
56
- "port number with : as a separator, " ,
57
- token );
58
- } else {
59
- ds_put_format (& errors , "%s: should be an IP address, " , token );
60
- }
96
+ if (!ovn_lb_backend_init_explicit (lb_vip , backend , token , & errors )) {
61
97
continue ;
62
98
}
63
99
64
- if (lb_vip -> address_family != backend_addr_family ) {
65
- free (backend -> ip_str );
66
- ds_put_format (& errors , "%s: IP address family is different from "
67
- "VIP %s, " ,
68
- token , lb_vip -> vip_str );
69
- continue ;
70
- }
71
-
72
- if (lb_vip -> port_str ) {
73
- if (!backend -> port ) {
74
- free (backend -> ip_str );
75
- ds_put_format (& errors , "%s: should be an IP address and "
76
- "a port number with : as a separator, " ,
77
- token );
78
- continue ;
79
- }
80
- } else {
81
- if (backend -> port ) {
82
- free (backend -> ip_str );
83
- ds_put_format (& errors , "%s: should be an IP address, " , token );
84
- continue ;
85
- }
86
- }
87
-
88
- backend -> port_str =
89
- backend -> port ? xasprintf ("%" PRIu16 , backend -> port ) : NULL ;
90
100
lb_vip -> n_backends ++ ;
91
101
}
92
102
free (tokstr );
@@ -118,6 +128,47 @@ ovn_lb_vip_init_explicit(struct ovn_lb_vip *lb_vip, const char *lb_key,
118
128
return ovn_lb_backends_init_explicit (lb_vip , lb_value );
119
129
}
120
130
131
+ static bool
132
+ ovn_lb_backend_init_template (struct ovn_lb_backend * backend , const char * token ,
133
+ struct ds * errors )
134
+ {
135
+ char * atom = xstrdup (token );
136
+ char * save_ptr = NULL ;
137
+ bool success = false;
138
+ char * backend_ip = NULL ;
139
+ char * backend_port = NULL ;
140
+
141
+ for (char * subatom = strtok_r (atom , ":" , & save_ptr ); subatom ;
142
+ subatom = strtok_r (NULL , ":" , & save_ptr )) {
143
+ if (backend_ip && backend_port ) {
144
+ success = false;
145
+ break ;
146
+ }
147
+ success = true;
148
+ if (!backend_ip ) {
149
+ backend_ip = xstrdup (subatom );
150
+ } else {
151
+ backend_port = xstrdup (subatom );
152
+ }
153
+ }
154
+
155
+ if (success ) {
156
+ backend -> ip_str = backend_ip ;
157
+ backend -> port_str = backend_port ;
158
+ backend -> port = 0 ;
159
+ memset (& backend -> ip , 0 , sizeof backend -> ip );
160
+ } else {
161
+ ds_put_format (errors , "%s: should be a template of the form: "
162
+ "'^backendip_variable1[:^port_variable1|:port]', " ,
163
+ atom );
164
+ free (backend_port );
165
+ free (backend_ip );
166
+ }
167
+ free (atom );
168
+
169
+ return success ;
170
+ }
171
+
121
172
/* Parses backends of a templated LB VIP.
122
173
* For now only the following template forms are supported:
123
174
* A.
@@ -130,6 +181,8 @@ ovn_lb_vip_init_explicit(struct ovn_lb_vip *lb_vip, const char *lb_key,
130
181
* IP1_2:PORT1_2 on chassis-2
131
182
* and 'backends_variable2' may expand to IP2_1:PORT2_1 on chassis-1
132
183
* IP2_2:PORT2_2 on chassis-2
184
+ * C.
185
+ * backendip1[:port],backendip2[:port]
133
186
*/
134
187
static char *
135
188
ovn_lb_backends_init_template (struct ovn_lb_vip * lb_vip , const char * value_ )
@@ -140,50 +193,28 @@ ovn_lb_backends_init_template(struct ovn_lb_vip *lb_vip, const char *value_)
140
193
size_t n_allocated_backends = 0 ;
141
194
lb_vip -> n_backends = 0 ;
142
195
143
- for (char * backend = strtok_r (value , "," , & save_ptr ); backend ;
144
- backend = strtok_r (NULL , "," , & save_ptr )) {
145
-
146
- char * atom = xstrdup (backend );
147
- char * save_ptr2 = NULL ;
148
- bool success = false;
149
- char * backend_ip = NULL ;
150
- char * backend_port = NULL ;
196
+ for (char * token = strtok_r (value , "," , & save_ptr ); token ;
197
+ token = strtok_r (NULL , "," , & save_ptr )) {
151
198
152
- for (char * subatom = strtok_r (atom , ":" , & save_ptr2 ); subatom ;
153
- subatom = strtok_r (NULL , ":" , & save_ptr2 )) {
154
- if (backend_ip && backend_port ) {
155
- success = false;
156
- break ;
157
- }
158
- success = true;
159
- if (!backend_ip ) {
160
- backend_ip = xstrdup (subatom );
161
- } else {
162
- backend_port = xstrdup (subatom );
163
- }
199
+ if (lb_vip -> n_backends == n_allocated_backends ) {
200
+ lb_vip -> backends = x2nrealloc (lb_vip -> backends ,
201
+ & n_allocated_backends ,
202
+ sizeof * lb_vip -> backends );
164
203
}
165
204
166
- if (success ) {
167
- if (lb_vip -> n_backends == n_allocated_backends ) {
168
- lb_vip -> backends = x2nrealloc (lb_vip -> backends ,
169
- & n_allocated_backends ,
170
- sizeof * lb_vip -> backends );
205
+ struct ovn_lb_backend * backend = & lb_vip -> backends [lb_vip -> n_backends ];
206
+ if (token [0 ] && token [0 ] == '^' ) {
207
+ if (!ovn_lb_backend_init_template (backend , token , & errors )) {
208
+ continue ;
171
209
}
172
-
173
- struct ovn_lb_backend * lb_backend =
174
- & lb_vip -> backends [lb_vip -> n_backends ];
175
- lb_backend -> ip_str = backend_ip ;
176
- lb_backend -> port_str = backend_port ;
177
- lb_backend -> port = 0 ;
178
- lb_vip -> n_backends ++ ;
179
210
} else {
180
- ds_put_format (& errors , "%s: should be a template of the form: "
181
- "'^backendip_variable1[:^port_variable1|:port]', " ,
182
- atom );
183
- free (backend_port );
184
- free (backend_ip );
211
+ if (!ovn_lb_backend_init_explicit (lb_vip , backend ,
212
+ token , & errors )) {
213
+ continue ;
214
+ }
185
215
}
186
- free (atom );
216
+
217
+ lb_vip -> n_backends ++ ;
187
218
}
188
219
189
220
free (value );
@@ -231,23 +262,13 @@ ovn_lb_vip_init_template(struct ovn_lb_vip *lb_vip, const char *lb_key_,
231
262
232
263
/* Backends can either be templates or explicit IPs and ports. */
233
264
lb_vip -> address_family = address_family ;
234
- lb_vip -> template_backends = true;
235
265
char * template_error = ovn_lb_backends_init_template (lb_vip , lb_value );
236
266
237
267
if (template_error ) {
238
- lb_vip -> template_backends = false;
239
- ovn_lb_backends_clear (lb_vip );
240
-
241
- char * explicit_error = ovn_lb_backends_init_explicit (lb_vip , lb_value );
242
- if (explicit_error ) {
243
- char * error =
244
- xasprintf ("invalid backend: template (%s) OR explicit (%s)" ,
245
- template_error , explicit_error );
246
- free (explicit_error );
268
+ char * error = xasprintf ("invalid backend: template (%s)" ,
269
+ template_error );
247
270
free (template_error );
248
271
return error ;
249
- }
250
- free (template_error );
251
272
}
252
273
return NULL ;
253
274
}
@@ -274,14 +295,7 @@ ovn_lb_backends_destroy(struct ovn_lb_vip *vip)
274
295
free (vip -> backends [i ].ip_str );
275
296
free (vip -> backends [i ].port_str );
276
297
}
277
- }
278
-
279
- static void
280
- ovn_lb_backends_clear (struct ovn_lb_vip * vip )
281
- {
282
- ovn_lb_backends_destroy (vip );
283
- vip -> backends = NULL ;
284
- vip -> n_backends = 0 ;
298
+ free (vip -> backends );
285
299
}
286
300
287
301
void
@@ -290,7 +304,6 @@ ovn_lb_vip_destroy(struct ovn_lb_vip *vip)
290
304
free (vip -> vip_str );
291
305
free (vip -> port_str );
292
306
ovn_lb_backends_destroy (vip );
293
- free (vip -> backends );
294
307
}
295
308
296
309
static void
@@ -320,11 +333,11 @@ ovn_lb_vip_format(const struct ovn_lb_vip *vip, struct ds *s, bool template)
320
333
void
321
334
ovn_lb_vip_backends_format (const struct ovn_lb_vip * vip , struct ds * s )
322
335
{
323
- bool needs_brackets = vip -> address_family == AF_INET6 && vip -> port_str
324
- && !vip -> template_backends ;
325
336
for (size_t i = 0 ; i < vip -> n_backends ; i ++ ) {
326
337
struct ovn_lb_backend * backend = & vip -> backends [i ];
327
-
338
+ bool needs_brackets = vip -> address_family == AF_INET6 &&
339
+ vip -> port_str &&
340
+ !ipv6_addr_equals (& backend -> ip , & in6addr_any );
328
341
if (needs_brackets ) {
329
342
ds_put_char (s , '[' );
330
343
}
0 commit comments