Branch data Line data Source code
1 : : /* Copyright (c) 2015, 2016 Nicira, Inc.
2 : : *
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:
6 : : *
7 : : * http://www.apache.org/licenses/LICENSE-2.0
8 : : *
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.
14 : : */
15 : :
16 : : #include <config.h>
17 : :
18 : : #include "lport.h"
19 : : #include "hash.h"
20 : : #include "openvswitch/vlog.h"
21 : : #include "ovn/lib/ovn-sb-idl.h"
22 : :
23 : 94 : VLOG_DEFINE_THIS_MODULE(lport);
24 : :
25 : : /* A logical port. */
26 : : struct lport {
27 : : struct hmap_node name_node; /* Index by name. */
28 : : struct hmap_node key_node; /* Index by (dp_key, port_key). */
29 : : const struct sbrec_port_binding *pb;
30 : : };
31 : :
32 : : void
33 : 3167 : lport_index_init(struct lport_index *lports, struct ovsdb_idl *ovnsb_idl)
34 : : {
35 : 3167 : hmap_init(&lports->by_name);
36 : 3167 : hmap_init(&lports->by_key);
37 : :
38 : : const struct sbrec_port_binding *pb;
39 [ + + ]: 65858 : SBREC_PORT_BINDING_FOR_EACH (pb, ovnsb_idl) {
40 [ - + ]: 62691 : if (lport_lookup_by_name(lports, pb->logical_port)) {
41 : : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
42 [ # # ]: 0 : VLOG_WARN_RL(&rl, "duplicate logical port name '%s'",
43 : : pb->logical_port);
44 : 0 : continue;
45 : : }
46 : :
47 : 62691 : struct lport *p = xmalloc(sizeof *p);
48 : 62691 : hmap_insert(&lports->by_name, &p->name_node,
49 : : hash_string(pb->logical_port, 0));
50 : 62691 : hmap_insert(&lports->by_key, &p->key_node,
51 : : hash_int(pb->tunnel_key, pb->datapath->tunnel_key));
52 : 62691 : p->pb = pb;
53 : : }
54 : 3167 : }
55 : :
56 : : void
57 : 3167 : lport_index_destroy(struct lport_index *lports)
58 : : {
59 : : /* Destroy all of the "struct lport"s.
60 : : *
61 : : * We don't have to remove the node from both indexes. */
62 : : struct lport *port, *next;
63 [ + + ][ - + ]: 65858 : HMAP_FOR_EACH_SAFE (port, next, name_node, &lports->by_name) {
[ + + ]
64 : 62691 : hmap_remove(&lports->by_name, &port->name_node);
65 : 62691 : free(port);
66 : : }
67 : :
68 : 3167 : hmap_destroy(&lports->by_name);
69 : 3167 : hmap_destroy(&lports->by_key);
70 : 3167 : }
71 : :
72 : : /* Finds and returns the lport with the given 'name', or NULL if no such lport
73 : : * exists. */
74 : : const struct sbrec_port_binding *
75 : 516886 : lport_lookup_by_name(const struct lport_index *lports, const char *name)
76 : : {
77 : : const struct lport *lport;
78 [ + + ][ - + ]: 516886 : HMAP_FOR_EACH_WITH_HASH (lport, name_node, hash_string(name, 0),
79 : : &lports->by_name) {
80 [ + - ]: 443572 : if (!strcmp(lport->pb->logical_port, name)) {
81 : 443572 : return lport->pb;
82 : : }
83 : : }
84 : 73314 : return NULL;
85 : : }
86 : :
87 : : const struct sbrec_port_binding *
88 : 230 : lport_lookup_by_key(const struct lport_index *lports,
89 : : uint32_t dp_key, uint16_t port_key)
90 : : {
91 : : const struct lport *lport;
92 [ + - ][ # # ]: 230 : HMAP_FOR_EACH_WITH_HASH (lport, key_node, hash_int(port_key, dp_key),
93 : : &lports->by_key) {
94 [ + - ]: 230 : if (port_key == lport->pb->tunnel_key
95 [ + - ]: 230 : && dp_key == lport->pb->datapath->tunnel_key) {
96 : 230 : return lport->pb;
97 : : }
98 : : }
99 : 0 : return NULL;
100 : : }
101 : :
102 : : struct mcgroup {
103 : : struct hmap_node dp_name_node; /* Index by (logical datapath, name). */
104 : : const struct sbrec_multicast_group *mg;
105 : : };
106 : :
107 : : void
108 : 3167 : mcgroup_index_init(struct mcgroup_index *mcgroups, struct ovsdb_idl *ovnsb_idl)
109 : : {
110 : 3167 : hmap_init(&mcgroups->by_dp_name);
111 : :
112 : : const struct sbrec_multicast_group *mg;
113 [ + + ]: 14341 : SBREC_MULTICAST_GROUP_FOR_EACH (mg, ovnsb_idl) {
114 : 11174 : const struct uuid *dp_uuid = &mg->datapath->header_.uuid;
115 [ - + ]: 11174 : if (mcgroup_lookup_by_dp_name(mcgroups, mg->datapath, mg->name)) {
116 : : static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 1);
117 [ # # ]: 0 : VLOG_WARN_RL(&rl, "datapath "UUID_FMT" contains duplicate "
118 : : "multicast group '%s'", UUID_ARGS(dp_uuid), mg->name);
119 : 0 : continue;
120 : : }
121 : :
122 : 11174 : struct mcgroup *m = xmalloc(sizeof *m);
123 : 11174 : hmap_insert(&mcgroups->by_dp_name, &m->dp_name_node,
124 : : hash_string(mg->name, uuid_hash(dp_uuid)));
125 : 11174 : m->mg = mg;
126 : : }
127 : 3167 : }
128 : :
129 : : void
130 : 3167 : mcgroup_index_destroy(struct mcgroup_index *mcgroups)
131 : : {
132 : : struct mcgroup *mcgroup, *next;
133 [ + + ][ - + ]: 14341 : HMAP_FOR_EACH_SAFE (mcgroup, next, dp_name_node, &mcgroups->by_dp_name) {
[ + + ]
134 : 11174 : hmap_remove(&mcgroups->by_dp_name, &mcgroup->dp_name_node);
135 : 11174 : free(mcgroup);
136 : : }
137 : :
138 : 3167 : hmap_destroy(&mcgroups->by_dp_name);
139 : 3167 : }
140 : :
141 : : const struct sbrec_multicast_group *
142 : 21418 : mcgroup_lookup_by_dp_name(const struct mcgroup_index *mcgroups,
143 : : const struct sbrec_datapath_binding *dp,
144 : : const char *name)
145 : : {
146 : 21418 : const struct uuid *dp_uuid = &dp->header_.uuid;
147 : : const struct mcgroup *mcgroup;
148 [ + + ][ - + ]: 21418 : HMAP_FOR_EACH_WITH_HASH (mcgroup, dp_name_node,
149 : : hash_string(name, uuid_hash(dp_uuid)),
150 : : &mcgroups->by_dp_name) {
151 [ + - ]: 10244 : if (uuid_equals(&mcgroup->mg->datapath->header_.uuid, dp_uuid)
152 [ + - ]: 10244 : && !strcmp(mcgroup->mg->name, name)) {
153 : 10244 : return mcgroup->mg;
154 : : }
155 : : }
156 : 11174 : return NULL;
157 : : }
|