]>
git.proxmox.com Git - ovs.git/blob - ofproto/ofproto-dpif-xlate-cache.c
1 /* Copyright (c) 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016 Nicira, 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. */
17 #include "ofproto/ofproto-dpif-xlate-cache.h"
19 #include <arpa/inet.h>
22 #include <netinet/in.h>
23 #include <sys/socket.h>
29 #include "byte-order.h"
32 #include "dp-packet.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"
45 #include "tnl-neigh-cache.h"
48 VLOG_DEFINE_THIS_MODULE(ofproto_xlate_cache
);
51 xlate_cache_init(struct xlate_cache
*xcache
)
53 ofpbuf_init(&xcache
->entries
, 120);
59 struct xlate_cache
*xcache
= xmalloc(sizeof *xcache
);
60 xlate_cache_init(xcache
);
65 xlate_cache_add_entry(struct xlate_cache
*xcache
, enum xc_type type
)
67 struct xc_entry
*entry
;
69 entry
= ofpbuf_put_zeros(&xcache
->entries
, sizeof *entry
);
76 xlate_cache_netdev(struct xc_entry
*entry
, const struct dpif_flow_stats
*stats
)
79 netdev_vport_inc_tx(entry
->dev
.tx
, stats
);
82 netdev_vport_inc_rx(entry
->dev
.rx
, stats
);
85 bfd_account_rx(entry
->dev
.bfd
, stats
);
89 /* Push stats and perform side effects of flow translation. */
91 xlate_push_stats_entry(struct xc_entry
*entry
,
92 struct dpif_flow_stats
*stats
)
96 switch (entry
->type
) {
98 ofproto_dpif_credit_table_stats(entry
->table
.ofproto
,
101 ? stats
->n_packets
: 0,
103 ? 0 : stats
->n_packets
);
106 rule_dpif_credit_stats(entry
->rule
, stats
);
109 bond_account(entry
->bond
.bond
, entry
->bond
.flow
,
110 entry
->bond
.vid
, stats
->n_bytes
);
113 xlate_cache_netdev(entry
, stats
);
116 netflow_flow_update(entry
->nf
.netflow
, entry
->nf
.flow
,
117 entry
->nf
.iface
, stats
);
120 mirror_update_stats(entry
->mirror
.mbridge
,
121 entry
->mirror
.mirrors
,
122 stats
->n_packets
, stats
->n_bytes
);
126 error
= ofproto_flow_mod_learn(entry
->learn
.ofm
, true,
127 entry
->learn
.limit
, NULL
);
129 static struct vlog_rate_limit rl
= VLOG_RATE_LIMIT_INIT(1, 5);
130 VLOG_WARN_RL(&rl
, "xcache LEARN action execution failed.");
135 xlate_mac_learning_update(entry
->normal
.ofproto
,
136 entry
->normal
.in_port
,
137 entry
->normal
.dl_src
,
139 entry
->normal
.is_gratuitous_arp
);
142 if (stats
->tcp_flags
& (TCP_FIN
| TCP_RST
)) {
143 ofproto_rule_reduce_timeouts(&entry
->fin
.rule
->up
, entry
->fin
.idle
,
148 group_dpif_credit_stats(entry
->group
.group
, entry
->group
.bucket
,
152 /* Lookup neighbor to avoid timeout. */
153 tnl_neigh_lookup(entry
->tnl_neigh_cache
.br_name
,
154 &entry
->tnl_neigh_cache
.d_ipv6
, &dmac
);
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. */
163 case XC_TUNNEL_HEADER
:
164 if (entry
->tunnel_hdr
.operation
== ADD
) {
165 stats
->n_bytes
+= stats
->n_packets
* entry
->tunnel_hdr
.hdr_size
;
167 stats
->n_bytes
-= stats
->n_packets
* entry
->tunnel_hdr
.hdr_size
;
177 xlate_push_stats(struct xlate_cache
*xcache
,
178 struct dpif_flow_stats
*stats
)
180 if (!stats
->n_packets
) {
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
);
192 xlate_dev_unref(struct xc_entry
*entry
)
195 netdev_close(entry
->dev
.tx
);
198 netdev_close(entry
->dev
.rx
);
200 if (entry
->dev
.bfd
) {
201 bfd_unref(entry
->dev
.bfd
);
206 xlate_cache_clear_netflow(struct netflow
*netflow
, struct flow
*flow
)
208 netflow_flow_clear(netflow
, flow
);
209 netflow_unref(netflow
);
214 xlate_cache_clear_entry(struct xc_entry
*entry
)
216 switch (entry
->type
) {
220 ofproto_rule_unref(&entry
->rule
->up
);
223 free(entry
->bond
.flow
);
224 bond_unref(entry
->bond
.bond
);
227 xlate_dev_unref(entry
);
230 xlate_cache_clear_netflow(entry
->nf
.netflow
, entry
->nf
.flow
);
233 mbridge_unref(entry
->mirror
.mbridge
);
236 ofproto_flow_mod_uninit(entry
->learn
.ofm
);
237 free(entry
->learn
.ofm
);
242 /* 'u.fin.rule' is always already held as a XC_RULE, which
243 * has already released it's reference above. */
246 ofproto_group_unref(&entry
->group
.group
->up
);
251 if (entry
->controller
.am
) {
252 ofproto_async_msg_free(entry
->controller
.am
);
253 entry
->controller
.am
= NULL
;
256 case XC_TUNNEL_HEADER
:
264 xlate_cache_clear(struct xlate_cache
*xcache
)
270 struct xc_entry
*entry
;
271 struct ofpbuf entries
= xcache
->entries
;
272 XC_ENTRY_FOR_EACH (entry
, &entries
) {
273 xlate_cache_clear_entry(entry
);
276 ofpbuf_clear(&xcache
->entries
);
280 xlate_cache_uninit(struct xlate_cache
*xcache
)
282 xlate_cache_clear(xcache
);
283 ofpbuf_uninit(&xcache
->entries
);
287 xlate_cache_delete(struct xlate_cache
*xcache
)
289 xlate_cache_uninit(xcache
);
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.
298 xlate_cache_steal_entries(struct xlate_cache
*dst
, struct xlate_cache
*src
)
303 struct ofpbuf
*src_entries
= &src
->entries
;
304 struct ofpbuf
*dst_entries
= &dst
->entries
;
307 p
= ofpbuf_put_uninit(dst_entries
, src_entries
->size
);
308 memcpy(p
, src_entries
->data
, src_entries
->size
);
309 ofpbuf_clear(src_entries
);