]> git.proxmox.com Git - ovs.git/blob - ofproto/ofproto-dpif-xlate-cache.c
dpif-netdev: Change polled_queue to use dp_netdev_rxq.
[ovs.git] / ofproto / ofproto-dpif-xlate-cache.c
1 /* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 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 #include <config.h>
16
17 #include "ofproto/ofproto-dpif-xlate-cache.h"
18
19 #include <arpa/inet.h>
20 #include <errno.h>
21 #include <net/if.h>
22 #include <netinet/in.h>
23 #include <sys/socket.h>
24
25 #include "bfd.h"
26 #include "bitmap.h"
27 #include "bond.h"
28 #include "bundle.h"
29 #include "byte-order.h"
30 #include "connmgr.h"
31 #include "coverage.h"
32 #include "dp-packet.h"
33 #include "dpif.h"
34 #include "learn.h"
35 #include "mac-learning.h"
36 #include "netdev-vport.h"
37 #include "ofproto/ofproto-dpif-mirror.h"
38 #include "ofproto/ofproto-dpif-xlate.h"
39 #include "ofproto/ofproto-dpif.h"
40 #include "ofproto/ofproto-provider.h"
41 #include "openvswitch/dynamic-string.h"
42 #include "openvswitch/vlog.h"
43 #include "ovs-router.h"
44 #include "packets.h"
45 #include "tnl-neigh-cache.h"
46 #include "util.h"
47
48 VLOG_DEFINE_THIS_MODULE(ofproto_xlate_cache);
49
50 void
51 xlate_cache_init(struct xlate_cache *xcache)
52 {
53 ofpbuf_init(&xcache->entries, 120);
54 }
55
56 struct xlate_cache *
57 xlate_cache_new(void)
58 {
59 struct xlate_cache *xcache = xmalloc(sizeof *xcache);
60 xlate_cache_init(xcache);
61 return xcache;
62 }
63
64 struct xc_entry *
65 xlate_cache_add_entry(struct xlate_cache *xcache, enum xc_type type)
66 {
67 struct xc_entry *entry;
68
69 entry = ofpbuf_put_zeros(&xcache->entries, sizeof *entry);
70 entry->type = type;
71
72 return entry;
73 }
74
75 static void
76 xlate_cache_netdev(struct xc_entry *entry, const struct dpif_flow_stats *stats)
77 {
78 if (entry->dev.tx) {
79 netdev_vport_inc_tx(entry->dev.tx, stats);
80 }
81 if (entry->dev.rx) {
82 netdev_vport_inc_rx(entry->dev.rx, stats);
83 }
84 if (entry->dev.bfd) {
85 bfd_account_rx(entry->dev.bfd, stats);
86 }
87 }
88
89 /* Push stats and perform side effects of flow translation. */
90 void
91 xlate_push_stats_entry(struct xc_entry *entry,
92 struct dpif_flow_stats *stats)
93 {
94 struct eth_addr dmac;
95
96 switch (entry->type) {
97 case XC_TABLE:
98 ofproto_dpif_credit_table_stats(entry->table.ofproto,
99 entry->table.id,
100 entry->table.match
101 ? stats->n_packets : 0,
102 entry->table.match
103 ? 0 : stats->n_packets);
104 break;
105 case XC_RULE:
106 rule_dpif_credit_stats(entry->rule, stats);
107 break;
108 case XC_BOND:
109 bond_account(entry->bond.bond, entry->bond.flow,
110 entry->bond.vid, stats->n_bytes);
111 break;
112 case XC_NETDEV:
113 xlate_cache_netdev(entry, stats);
114 break;
115 case XC_NETFLOW:
116 netflow_flow_update(entry->nf.netflow, entry->nf.flow,
117 entry->nf.iface, stats);
118 break;
119 case XC_MIRROR:
120 mirror_update_stats(entry->mirror.mbridge,
121 entry->mirror.mirrors,
122 stats->n_packets, stats->n_bytes);
123 break;
124 case XC_LEARN: {
125 enum ofperr error;
126 error = ofproto_flow_mod_learn(entry->learn.ofm, true,
127 entry->learn.limit, NULL);
128 if (error) {
129 static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
130 VLOG_WARN_RL(&rl, "xcache LEARN action execution failed.");
131 }
132 break;
133 }
134 case XC_NORMAL:
135 xlate_mac_learning_update(entry->normal.ofproto,
136 entry->normal.in_port,
137 entry->normal.dl_src,
138 entry->normal.vlan,
139 entry->normal.is_gratuitous_arp);
140 break;
141 case XC_FIN_TIMEOUT:
142 if (stats->tcp_flags & (TCP_FIN | TCP_RST)) {
143 ofproto_rule_reduce_timeouts(&entry->fin.rule->up, entry->fin.idle,
144 entry->fin.hard);
145 }
146 break;
147 case XC_GROUP:
148 group_dpif_credit_stats(entry->group.group, entry->group.bucket,
149 stats);
150 break;
151 case XC_TNL_NEIGH:
152 /* Lookup neighbor to avoid timeout. */
153 tnl_neigh_lookup(entry->tnl_neigh_cache.br_name,
154 &entry->tnl_neigh_cache.d_ipv6, &dmac);
155 break;
156 case XC_CONTROLLER:
157 if (entry->controller.am) {
158 ofproto_dpif_send_async_msg(entry->controller.ofproto,
159 entry->controller.am);
160 entry->controller.am = NULL; /* One time only. */
161 }
162 break;
163 case XC_TUNNEL_HEADER:
164 if (entry->tunnel_hdr.operation == ADD) {
165 stats->n_bytes += stats->n_packets * entry->tunnel_hdr.hdr_size;
166 } else {
167 stats->n_bytes -= stats->n_packets * entry->tunnel_hdr.hdr_size;
168 }
169
170 break;
171 default:
172 OVS_NOT_REACHED();
173 }
174 }
175
176 void
177 xlate_push_stats(struct xlate_cache *xcache,
178 struct dpif_flow_stats *stats)
179 {
180 if (!stats->n_packets) {
181 return;
182 }
183
184 struct xc_entry *entry;
185 struct ofpbuf entries = xcache->entries;
186 XC_ENTRY_FOR_EACH (entry, &entries) {
187 xlate_push_stats_entry(entry, stats);
188 }
189 }
190
191 static void
192 xlate_dev_unref(struct xc_entry *entry)
193 {
194 if (entry->dev.tx) {
195 netdev_close(entry->dev.tx);
196 }
197 if (entry->dev.rx) {
198 netdev_close(entry->dev.rx);
199 }
200 if (entry->dev.bfd) {
201 bfd_unref(entry->dev.bfd);
202 }
203 }
204
205 static void
206 xlate_cache_clear_netflow(struct netflow *netflow, struct flow *flow)
207 {
208 netflow_flow_clear(netflow, flow);
209 netflow_unref(netflow);
210 free(flow);
211 }
212
213 void
214 xlate_cache_clear_entry(struct xc_entry *entry)
215 {
216 switch (entry->type) {
217 case XC_TABLE:
218 break;
219 case XC_RULE:
220 ofproto_rule_unref(&entry->rule->up);
221 break;
222 case XC_BOND:
223 free(entry->bond.flow);
224 bond_unref(entry->bond.bond);
225 break;
226 case XC_NETDEV:
227 xlate_dev_unref(entry);
228 break;
229 case XC_NETFLOW:
230 xlate_cache_clear_netflow(entry->nf.netflow, entry->nf.flow);
231 break;
232 case XC_MIRROR:
233 mbridge_unref(entry->mirror.mbridge);
234 break;
235 case XC_LEARN:
236 ofproto_flow_mod_uninit(entry->learn.ofm);
237 free(entry->learn.ofm);
238 break;
239 case XC_NORMAL:
240 break;
241 case XC_FIN_TIMEOUT:
242 /* 'u.fin.rule' is always already held as a XC_RULE, which
243 * has already released it's reference above. */
244 break;
245 case XC_GROUP:
246 ofproto_group_unref(&entry->group.group->up);
247 break;
248 case XC_TNL_NEIGH:
249 break;
250 case XC_CONTROLLER:
251 if (entry->controller.am) {
252 ofproto_async_msg_free(entry->controller.am);
253 entry->controller.am = NULL;
254 }
255 break;
256 case XC_TUNNEL_HEADER:
257 break;
258 default:
259 OVS_NOT_REACHED();
260 }
261 }
262
263 void
264 xlate_cache_clear(struct xlate_cache *xcache)
265 {
266 if (!xcache) {
267 return;
268 }
269
270 struct xc_entry *entry;
271 struct ofpbuf entries = xcache->entries;
272 XC_ENTRY_FOR_EACH (entry, &entries) {
273 xlate_cache_clear_entry(entry);
274 }
275
276 ofpbuf_clear(&xcache->entries);
277 }
278
279 void
280 xlate_cache_uninit(struct xlate_cache *xcache)
281 {
282 xlate_cache_clear(xcache);
283 ofpbuf_uninit(&xcache->entries);
284 }
285
286 void
287 xlate_cache_delete(struct xlate_cache *xcache)
288 {
289 xlate_cache_uninit(xcache);
290 free(xcache);
291 }
292
293 /* Append all the entries in src into dst and remove them from src.
294 * The caller must own both xc-caches to use this function.
295 * The 'src' entries are not freed in this function as its owned by caller.
296 */
297 void
298 xlate_cache_steal_entries(struct xlate_cache *dst, struct xlate_cache *src)
299 {
300 if (!dst || !src) {
301 return;
302 }
303 struct ofpbuf *src_entries = &src->entries;
304 struct ofpbuf *dst_entries = &dst->entries;
305 void *p;
306
307 p = ofpbuf_put_uninit(dst_entries, src_entries->size);
308 memcpy(p, src_entries->data, src_entries->size);
309 ofpbuf_clear(src_entries);
310 }