[ovs-dev] [RFC PATCH v2 5/5] ofproto-dpif: Basic hooks for rewriting tunnel packets.
Jesse Gross
jesse at nicira.com
Fri Sep 28 22:12:19 UTC 2012
This is a basic set of hooks into the ofproto-dpif code so that
tunneled packets can be have their flows rewritten to reflect the
outward facing view of how ports are laid out. This is far from
being a comprehensive layer and should be replaced once a better
level of indirection is available.
Signed-off-by: Jesse Gross <jesse at nicira.com>
---
ofproto/ofproto-dpif.c | 40 ++++++++++++++++++++++++++++++++--------
1 file changed, 32 insertions(+), 8 deletions(-)
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index ff6df41..6fbe406 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -50,6 +50,7 @@
#include "poll-loop.h"
#include "simap.h"
#include "timer.h"
+#include "tunnel.h"
#include "unaligned.h"
#include "unixctl.h"
#include "vlan-bitmap.h"
@@ -803,6 +804,8 @@ construct(struct ofproto *ofproto_)
hmap_init(&ofproto->vlandev_map);
hmap_init(&ofproto->realdev_vid_map);
+ tnl_init();
+
hmap_insert(&all_ofproto_dpifs, &ofproto->all_ofproto_dpifs_node,
hash_string(ofproto->up.name, 0));
memset(&ofproto->stats, 0, sizeof ofproto->stats);
@@ -2536,6 +2539,11 @@ port_add(struct ofproto *ofproto_, struct netdev *netdev, uint16_t *ofp_portp)
error = dpif_port_add(ofproto->dpif, netdev, &odp_port);
if (!error) {
+ error = tnl_port_add(odp_port, odp_port, netdev);
+ if (error) {
+ dpif_port_del(ofproto->dpif, odp_port);
+ return error;
+ }
*ofp_portp = odp_port_to_ofp_port(odp_port);
}
return error;
@@ -2545,9 +2553,12 @@ static int
port_del(struct ofproto *ofproto_, uint16_t ofp_port)
{
struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
+ uint16_t odp_port = ofp_port_to_odp_port(ofp_port);
int error;
- error = dpif_port_del(ofproto->dpif, ofp_port_to_odp_port(ofp_port));
+ tnl_port_del(odp_port);
+
+ error = dpif_port_del(ofproto->dpif, odp_port);
if (!error) {
struct ofport_dpif *ofport = get_ofp_port(ofproto, ofp_port);
if (ofport) {
@@ -3025,8 +3036,9 @@ handle_flow_miss(struct ofproto_dpif *ofproto, struct flow_miss *miss,
* an ODP_FIT_* value that indicates how well 'key' fits our expectations for
* what a flow key should contain.
*
- * This function also includes some logic to help make VLAN splinters
- * transparent to the rest of the upcall processing logic. In particular, if
+ * This function also includes some logic to help with ports that have special
+ * meaning to their flows such as tunnels and VLAN splinters. Tunnels may
+ * map their source and destination addresses to a logical port whereas if
* the extracted in_port is a VLAN splinter port, it replaces flow->in_port by
* the "real" port, sets flow->vlan_tci correctly for the VLAN of the VLAN
* splinter port, and pushes a VLAN header onto 'packet' (if it is nonnull).
@@ -3043,13 +3055,21 @@ ofproto_dpif_extract_flow_key(const struct ofproto_dpif *ofproto,
struct ofpbuf *packet)
{
enum odp_key_fitness fitness;
+ bool adjusted;
+ int err;
fitness = odp_flow_key_to_flow(key, key_len, flow);
if (fitness == ODP_FIT_ERROR) {
return fitness;
}
- *initial_tci = flow->vlan_tci;
+ err = tnl_port_receive(flow, &adjusted);
+ if (err) {
+ /* XXX: We should really install a drop flow here. */
+ return ODP_FIT_ERROR;
+ }
+
+ *initial_tci = flow->vlan_tci;
if (vsp_adjust_flow(ofproto, flow)) {
if (packet) {
/* Make the packet resemble the flow, so that it gets sent to an
@@ -3069,10 +3089,12 @@ ofproto_dpif_extract_flow_key(const struct ofproto_dpif *ofproto,
eth_push_vlan(packet, flow->vlan_tci);
}
- /* Let the caller know that we can't reproduce 'key' from 'flow'. */
- if (fitness == ODP_FIT_PERFECT) {
- fitness = ODP_FIT_TOO_MUCH;
- }
+ adjusted = true;
+ }
+
+ /* Let the caller know that we can't reproduce 'key' from 'flow'. */
+ if (adjusted && fitness == ODP_FIT_PERFECT) {
+ fitness = ODP_FIT_TOO_MUCH;
}
return fitness;
@@ -4981,6 +5003,8 @@ compose_output_action__(struct action_xlate_ctx *ctx, uint16_t ofp_port,
if (out_port != odp_port) {
ctx->flow.vlan_tci = htons(0);
}
+ out_port = tnl_port_send(&ctx->flow, out_port);
+
commit_odp_actions(&ctx->flow, &ctx->base_flow, ctx->odp_actions);
nl_msg_put_u32(ctx->odp_actions, OVS_ACTION_ATTR_OUTPUT, out_port);
--
1.7.9.5
More information about the dev
mailing list