]>
git.proxmox.com Git - ovs.git/blob - ovn/controller/gchassis.c
1 /* Copyright (c) 2017, Red Hat, Inc.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at:
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
21 #include "openvswitch/vlog.h"
22 #include "ovn/lib/chassis-index.h"
23 #include "ovn/lib/ovn-sb-idl.h"
25 VLOG_DEFINE_THIS_MODULE(gchassis
);
27 /* gateway_chassis ordering
30 compare_chassis_prio_(const void *a_
, const void *b_
)
32 const struct gateway_chassis
*gc_a
= a_
;
33 const struct gateway_chassis
*gc_b
= b_
;
34 int prio_diff
= gc_b
->db
->priority
- gc_a
->db
->priority
;
36 return strcmp(gc_b
->db
->name
, gc_a
->db
->name
);
42 gateway_chassis_get_ordered(const struct sbrec_port_binding
*binding
,
43 const struct chassis_index
*chassis_index
)
45 const char *redir_chassis_str
;
46 const struct sbrec_chassis
*redirect_chassis
= NULL
;
48 /* XXX: redirect-chassis SBDB option handling is supported for backwards
49 * compatibility with N-1 version of ovn-northd. This support can
50 * be removed in OVS 2.9 where Gateway_Chassis list on the port binding
51 * will always be populated by northd */
52 redir_chassis_str
= smap_get(&binding
->options
, "redirect-chassis");
54 if (redir_chassis_str
) {
55 redirect_chassis
= chassis_lookup_by_name(chassis_index
,
57 if (!redirect_chassis
) {
58 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 1);
59 VLOG_WARN_RL(&rl
, "chassis name (%s) in redirect-chassis option "
60 "of logical port %s not known",
61 redir_chassis_str
, binding
->logical_port
);
65 if (!redirect_chassis
&& binding
->n_gateway_chassis
== 0) {
69 struct gateway_chassis
*gateway_chassis
= NULL
;
72 if (binding
->n_gateway_chassis
) {
73 gateway_chassis
= xmalloc(sizeof *gateway_chassis
*
74 binding
->n_gateway_chassis
);
75 for (n
= 0; n
< binding
->n_gateway_chassis
; n
++) {
76 gateway_chassis
[n
].db
= binding
->gateway_chassis
[n
];
77 gateway_chassis
[n
].virtual_gwc
= false;
79 qsort(gateway_chassis
, n
, sizeof *gateway_chassis
,
80 compare_chassis_prio_
);
81 } else if (redirect_chassis
) {
82 /* When only redirect_chassis is available, return a single
83 * virtual entry that it's not on OVSDB, this way the code
84 * handling the returned list will be uniform, regardless
85 * of gateway_chassis being populated or redirect-chassis option
87 gateway_chassis
= xmalloc(sizeof *gateway_chassis
);
88 struct sbrec_gateway_chassis
*gwc
=
89 xzalloc(sizeof *gateway_chassis
->db
);
90 sbrec_gateway_chassis_init(gwc
);
91 gwc
->name
= xasprintf("%s_%s", binding
->logical_port
,
92 redirect_chassis
->name
);
93 gwc
->chassis
= CONST_CAST(struct sbrec_chassis
*, redirect_chassis
);
94 gateway_chassis
->db
= gwc
;
95 gateway_chassis
->virtual_gwc
= true;
99 struct ovs_list
*list
= NULL
;
101 list
= xmalloc(sizeof *list
);
105 for (i
= 0; i
< n
; i
++) {
106 ovs_list_push_back(list
, &gateway_chassis
[i
].node
);
114 gateway_chassis_contains(const struct ovs_list
*gateway_chassis
,
115 const struct sbrec_chassis
*chassis
) {
116 struct gateway_chassis
*chassis_item
;
117 if (gateway_chassis
) {
118 LIST_FOR_EACH (chassis_item
, node
, gateway_chassis
) {
119 if (chassis_item
->db
->chassis
120 && !strcmp(chassis_item
->db
->chassis
->name
, chassis
->name
)) {
129 gateway_chassis_destroy(struct ovs_list
*list
)
135 /* XXX: This loop is for backwards compatibility with redirect-chassis
136 * which we insert as a single virtual Gateway_Chassis on the ordered
138 struct gateway_chassis
*chassis_item
;
139 LIST_FOR_EACH (chassis_item
, node
, list
) {
140 if (chassis_item
->virtual_gwc
) {
141 free(chassis_item
->db
->name
);
142 free(CONST_CAST(struct sbrec_gateway_chassis
*, chassis_item
->db
));
146 free(ovs_list_front(list
));
151 gateway_chassis_in_pb_contains(const struct sbrec_port_binding
*binding
,
152 const struct sbrec_chassis
*chassis
)
154 if (!binding
|| !chassis
) {
158 /* XXX: redirect-chassis handling for backwards compatibility,
159 * with older ovs-northd during upgrade phase, can be removed
161 const char *redirect_chassis
= smap_get(&binding
->options
,
163 if (binding
->n_gateway_chassis
) {
165 for (n
= 0; n
< binding
->n_gateway_chassis
; n
++) {
166 if (binding
->gateway_chassis
[n
]->chassis
167 && !strcmp(binding
->gateway_chassis
[n
]->chassis
->name
,
172 } else if (redirect_chassis
) {
173 return !strcmp(redirect_chassis
, chassis
->name
);
180 gateway_chassis_is_active(const struct ovs_list
*gateway_chassis
,
181 const struct sbrec_chassis
*local_chassis
,
182 const struct sset
*active_tunnels
)
184 struct gateway_chassis
*gwc
;
187 || (gateway_chassis
&& ovs_list_is_empty(gateway_chassis
))) {
190 /* if there's only one chassis, and local chassis is on the list
191 * it's not HA and it's the equivalent of being active */
192 if (ovs_list_is_singleton(gateway_chassis
) &&
193 gateway_chassis_contains(gateway_chassis
, local_chassis
)) {
197 /* if there are no other tunnels active, we assume that the
198 * connection providing tunneling is down, hence we're down */
199 if (sset_is_empty(active_tunnels
)) {
203 /* gateway_chassis is an ordered list, by priority, of chassis
204 * hosting the redirect of the port */
205 LIST_FOR_EACH (gwc
, node
, gateway_chassis
) {
206 if (!gwc
->db
->chassis
) {
209 /* if we found the chassis on the list, and we didn't exit before
210 * on the active_tunnels check for other higher priority chassis
211 * being active, then this chassis is master. */
212 if (!strcmp(gwc
->db
->chassis
->name
, local_chassis
->name
)) {
215 /* if we find this specific chassis on the list to have an active
216 * tunnel, then 'local_chassis' is not master */
217 if (sset_contains(active_tunnels
, gwc
->db
->chassis
->name
)) {