summaryrefslogtreecommitdiff
path: root/ofproto
diff options
context:
space:
mode:
authorBen Pfaff <blp@ovn.org>2017-06-23 16:47:59 +0000
committerBen Pfaff <blp@ovn.org>2017-06-27 17:28:30 -0400
commit875ab13020b16269e0401b11fe0efc74e2cd952a (patch)
treeb474fb6bbb68be94bffd7ce6d4cd9a889408689c /ofproto
parent3d4b2e6eb74ed5bb5b35373aa8a489536938fee6 (diff)
downloadopenvswitch-875ab13020b16269e0401b11fe0efc74e2cd952a.tar.gz
userspace: Handling of versatile tunnel ports
In netdev_gre_build_header(), GRE protocol and VXLAN next_potocol is set based on packet_type of flow. If it's about an Ethernet packet, it is set to ETP_TYPE_TEB. Otherwise, if the name space is OFPHTN_ETHERNET, it is set according to the name space type. Signed-off-by: Jan Scheurich <jan.scheurich@ericsson.com> Signed-off-by: Ben Pfaff <blp@ovn.org>
Diffstat (limited to 'ofproto')
-rw-r--r--ofproto/ofproto-dpif-xlate.c35
-rw-r--r--ofproto/ofproto-dpif.c4
-rw-r--r--ofproto/tunnel.c27
3 files changed, 43 insertions, 23 deletions
diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
index 0fe6584b7..ce364b361 100644
--- a/ofproto/ofproto-dpif-xlate.c
+++ b/ofproto/ofproto-dpif-xlate.c
@@ -165,7 +165,7 @@ struct xport {
bool may_enable; /* May be enabled in bonds. */
bool is_tunnel; /* Is a tunnel port. */
- bool is_layer3; /* Is a layer 3 port. */
+ enum netdev_pt_mode pt_mode; /* packet_type handling. */
struct cfm *cfm; /* CFM handle or null. */
struct bfd *bfd; /* BFD handle or null. */
@@ -905,7 +905,7 @@ xlate_xport_set(struct xport *xport, odp_port_t odp_port,
xport->state = state;
xport->stp_port_no = stp_port_no;
xport->is_tunnel = is_tunnel;
- xport->is_layer3 = netdev_vport_is_layer3(netdev);
+ xport->pt_mode = netdev_get_pt_mode(netdev);
xport->may_enable = may_enable;
xport->odp_port = odp_port;
@@ -2691,7 +2691,10 @@ xlate_normal(struct xlate_ctx *ctx)
/* Learn source MAC. */
bool is_grat_arp = is_gratuitous_arp(flow, wc);
- if (ctx->xin->allow_side_effects && !in_port->is_layer3) {
+ if (ctx->xin->allow_side_effects
+ && flow->packet_type == htonl(PT_ETH)
+ && in_port->pt_mode != NETDEV_PT_LEGACY_L3
+ ) {
update_learning_table(ctx, in_xbundle, flow->dl_src, vlan,
is_grat_arp);
}
@@ -3351,15 +3354,19 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port,
return;
}
- if (flow->packet_type == htonl(PT_ETH) && xport->is_layer3) {
- /* Ethernet packet to L3 outport -> pop ethernet header. */
- flow->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE,
- ntohs(flow->dl_type));
- } else if (flow->packet_type != htonl(PT_ETH) && !xport->is_layer3) {
- /* L2 outport and non-ethernet packet_type -> add dummy eth header. */
- flow->packet_type = htonl(PT_ETH);
- flow->dl_dst = eth_addr_zero;
- flow->dl_src = eth_addr_zero;
+ if (flow->packet_type == htonl(PT_ETH)) {
+ /* Strip Ethernet header for legacy L3 port. */
+ if (xport->pt_mode == NETDEV_PT_LEGACY_L3) {
+ flow->packet_type = PACKET_TYPE_BE(OFPHTN_ETHERTYPE,
+ ntohs(flow->dl_type));
+ }
+ } else {
+ /* Add dummy Ethernet header for legacy L2 port. */
+ if (xport->pt_mode == NETDEV_PT_LEGACY_L2) {
+ flow->packet_type = htonl(PT_ETH);
+ flow->dl_dst = eth_addr_zero;
+ flow->dl_src = eth_addr_zero;
+ }
}
if (xport->peer) {
@@ -6394,8 +6401,8 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
struct xport *in_port = get_ofp_port(xbridge,
ctx.base_flow.in_port.ofp_port);
- if (flow->packet_type != htonl(PT_ETH) && in_port && in_port->is_layer3 &&
- ctx.table_id == 0) {
+ if (flow->packet_type != htonl(PT_ETH) && in_port &&
+ in_port->pt_mode == NETDEV_PT_LEGACY_L3 && ctx.table_id == 0) {
/* Add dummy Ethernet header to non-L2 packet if it's coming from a
* L3 port. So all packets will be L2 packets for lookup.
* The dl_type has already been set from the packet_type. */
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index cc325ddd7..d19d486d9 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -2893,7 +2893,7 @@ bundle_update(struct ofbundle *bundle)
bundle->floodable = true;
LIST_FOR_EACH (port, bundle_node, &bundle->ports) {
if (port->up.pp.config & OFPUTIL_PC_NO_FLOOD
- || netdev_vport_is_layer3(port->up.netdev)
+ || netdev_get_pt_mode(port->up.netdev) == NETDEV_PT_LEGACY_L3
|| (bundle->ofproto->stp && !stp_forward_in_state(port->stp_state))
|| (bundle->ofproto->rstp && !rstp_forward_in_state(port->rstp_state))) {
bundle->floodable = false;
@@ -2942,7 +2942,7 @@ bundle_add_port(struct ofbundle *bundle, ofp_port_t ofp_port,
port->bundle = bundle;
ovs_list_push_back(&bundle->ports, &port->bundle_node);
if (port->up.pp.config & OFPUTIL_PC_NO_FLOOD
- || netdev_vport_is_layer3(port->up.netdev)
+ || netdev_get_pt_mode(port->up.netdev) == NETDEV_PT_LEGACY_L3
|| (bundle->ofproto->stp && !stp_forward_in_state(port->stp_state))
|| (bundle->ofproto->rstp && !rstp_forward_in_state(port->rstp_state))) {
bundle->floodable = false;
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c
index fa99b3102..c6856a09e 100644
--- a/ofproto/tunnel.c
+++ b/ofproto/tunnel.c
@@ -50,7 +50,7 @@ struct tnl_match {
bool in_key_flow;
bool ip_src_flow;
bool ip_dst_flow;
- bool is_layer3;
+ enum netdev_pt_mode pt_mode;
};
struct tnl_port {
@@ -164,7 +164,7 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev,
tnl_port->match.ip_dst_flow = cfg->ip_dst_flow;
tnl_port->match.in_key_flow = cfg->in_key_flow;
tnl_port->match.odp_port = odp_port;
- tnl_port->match.is_layer3 = netdev_vport_is_layer3(netdev);
+ tnl_port->match.pt_mode = netdev_get_pt_mode(netdev);
map = tnl_match_map(&tnl_port->match);
existing_port = tnl_find_exact(&tnl_port->match, *map);
@@ -564,8 +564,20 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock)
match.in_key_flow = in_key_flow;
match.ip_dst_flow = ip_dst_flow;
match.ip_src_flow = ip_src == IP_SRC_FLOW;
- match.is_layer3 = flow->packet_type != htonl(PT_ETH);
+ /* Look for a legacy L2 or L3 tunnel port first. */
+ if (pt_ns(flow->packet_type) == OFPHTN_ETHERTYPE) {
+ match.pt_mode = NETDEV_PT_LEGACY_L3;
+ } else {
+ match.pt_mode = NETDEV_PT_LEGACY_L2;
+ }
+ tnl_port = tnl_find_exact(&match, map);
+ if (tnl_port) {
+ return tnl_port;
+ }
+
+ /* Then check for a packet type aware port. */
+ match.pt_mode = NETDEV_PT_AWARE;
tnl_port = tnl_find_exact(&match, map);
if (tnl_port) {
return tnl_port;
@@ -614,11 +626,12 @@ tnl_match_fmt(const struct tnl_match *match, struct ds *ds)
} else {
ds_put_format(ds, ", key=%#"PRIx64, ntohll(match->in_key));
}
- if (match->is_layer3) {
- ds_put_cstr(ds, ", layer3");
- }
- ds_put_format(ds, ", dp port=%"PRIu32, match->odp_port);
+ const char *pt_mode
+ = (match->pt_mode == NETDEV_PT_LEGACY_L2 ? "legacy_l2"
+ : match->pt_mode == NETDEV_PT_LEGACY_L3 ? "legacy_l3"
+ : "ptap");
+ ds_put_format(ds, ", %s, dp port=%"PRIu32, pt_mode, match->odp_port);
}
static void