Store the original IP address similarly to IPv4. Change the is_tunnel boolean to the outer protocol; null protocol indicates no tunnel.
Signed-off-by: Jiri Benc <jb...@redhat.com> --- ofproto/ofproto-dpif-xlate.c | 27 +++++++++++++++++---------- ofproto/ofproto-dpif-xlate.h | 2 +- ofproto/ofproto-dpif.c | 28 +++++++++++++++------------- 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c index f73787744db3..0307982c9c19 100644 --- a/ofproto/ofproto-dpif-xlate.c +++ b/ofproto/ofproto-dpif-xlate.c @@ -159,7 +159,8 @@ struct xport { struct hmap skb_priorities; /* Map of 'skb_priority_to_dscp's. */ bool may_enable; /* May be enabled in bonds. */ - bool is_tunnel; /* Is a tunnel port. */ + uint16_t tunnel_protocol; /* Tunnel underlying protocol. + * 0 when not a tunnel port. */ struct cfm *cfm; /* CFM handle or null. */ struct bfd *bfd; /* BFD handle or null. */ @@ -182,6 +183,7 @@ struct xlate_ctx { * if a tunnel is marked as 'ip_remote=flow', and the flow does not * actually set the tun_dst field. */ ovs_be32 orig_tunnel_ip_dst; + struct in6_addr orig_tunnel_ipv6_dst; /* Stack for the push and pop actions. Each stack element is of type * "union mf_subvalue". */ @@ -506,7 +508,8 @@ static void xlate_xport_set(struct xport *xport, odp_port_t odp_port, const struct bfd *bfd, const struct lldp *lldp, int stp_port_no, const struct rstp_port *rstp_port, enum ofputil_port_config config, - enum ofputil_port_state state, bool is_tunnel, + enum ofputil_port_state state, + uint16_t tunnel_protocol, bool may_enable); static void xlate_xbridge_remove(struct xlate_cfg *, struct xbridge *); static void xlate_xbundle_remove(struct xlate_cfg *, struct xbundle *); @@ -649,12 +652,12 @@ xlate_xport_set(struct xport *xport, odp_port_t odp_port, const struct bfd *bfd, const struct lldp *lldp, int stp_port_no, const struct rstp_port* rstp_port, enum ofputil_port_config config, enum ofputil_port_state state, - bool is_tunnel, bool may_enable) + uint16_t tunnel_protocol, bool may_enable) { xport->config = config; xport->state = state; xport->stp_port_no = stp_port_no; - xport->is_tunnel = is_tunnel; + xport->tunnel_protocol = tunnel_protocol; xport->may_enable = may_enable; xport->odp_port = odp_port; @@ -747,7 +750,7 @@ xlate_xport_copy(struct xbridge *xbridge, struct xbundle *xbundle, xlate_xport_set(new_xport, xport->odp_port, xport->netdev, xport->cfm, xport->bfd, xport->lldp, xport->stp_port_no, xport->rstp_port, xport->config, xport->state, - xport->is_tunnel, xport->may_enable); + xport->tunnel_protocol, xport->may_enable); if (xport->peer) { struct xport *peer = xport_lookup(new_xcfg, xport->peer->ofport); @@ -987,7 +990,7 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle, int stp_port_no, const struct rstp_port *rstp_port, const struct ofproto_port_queue *qdscp_list, size_t n_qdscp, enum ofputil_port_config config, - enum ofputil_port_state state, bool is_tunnel, + enum ofputil_port_state state, uint16_t tunnel_protocol, bool may_enable) { size_t i; @@ -1008,7 +1011,7 @@ xlate_ofport_set(struct ofproto_dpif *ofproto, struct ofbundle *ofbundle, ovs_assert(xport->ofp_port == ofp_port); xlate_xport_set(xport, odp_port, netdev, cfm, bfd, lldp, - stp_port_no, rstp_port, config, state, is_tunnel, + stp_port_no, rstp_port, config, state, tunnel_protocol, may_enable); if (xport->peer) { @@ -2904,7 +2907,7 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, } } - if (xport->is_tunnel) { + if (xport->tunnel_protocol) { /* Save tunnel metadata so that changes made due to * the Logical (tunnel) Port are not visible for any further * matches, while explicit set actions on tunnel metadata are. @@ -2915,7 +2918,10 @@ compose_output_action__(struct xlate_ctx *ctx, ofp_port_t ofp_port, xlate_report(ctx, "Tunneling decided against output"); goto out; /* restore flow_nw_tos */ } - if (flow->tunnel.ip_dst == ctx->orig_tunnel_ip_dst) { + if ((xport->tunnel_protocol == ETH_TYPE_IP && + flow->tunnel.ip_dst == ctx->orig_tunnel_ip_dst) || + (xport->tunnel_protocol == ETH_TYPE_IPV6 && + ipv6_addr_equals(&flow->tunnel.ipv6_dst, &ctx->orig_tunnel_ipv6_dst))) { xlate_report(ctx, "Not tunneling to our own address"); goto out; /* restore flow_nw_tos */ } @@ -4734,6 +4740,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) ctx.base_flow = *flow; memset(&ctx.base_flow.tunnel, 0, sizeof ctx.base_flow.tunnel); ctx.orig_tunnel_ip_dst = flow->tunnel.ip_dst; + ctx.orig_tunnel_ipv6_dst = flow->tunnel.ipv6_dst; if (!xin->skip_wildcards) { wc = &xout->wc; @@ -4893,7 +4900,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout) } /* Tunnel stats only for non-recirculated packets. */ - if (!xin->recirc && in_port && in_port->is_tunnel) { + if (!xin->recirc && in_port && in_port->tunnel_protocol) { if (ctx.xin->resubmit_stats) { netdev_vport_inc_rx(in_port->netdev, ctx.xin->resubmit_stats); if (in_port->bfd) { diff --git a/ofproto/ofproto-dpif-xlate.h b/ofproto/ofproto-dpif-xlate.h index 6c8ade308c77..84b9a02cc295 100644 --- a/ofproto/ofproto-dpif-xlate.h +++ b/ofproto/ofproto-dpif-xlate.h @@ -231,7 +231,7 @@ void xlate_ofport_set(struct ofproto_dpif *, struct ofbundle *, int stp_port_no, const struct rstp_port *rstp_port, const struct ofproto_port_queue *qdscp, size_t n_qdscp, enum ofputil_port_config, - enum ofputil_port_state, bool is_tunnel, + enum ofputil_port_state, uint16_t tunnel_protocol, bool may_enable); void xlate_ofport_remove(struct ofport_dpif *); diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c index bf893214b524..1d17761134cb 100644 --- a/ofproto/ofproto-dpif.c +++ b/ofproto/ofproto-dpif.c @@ -164,8 +164,8 @@ struct ofport_dpif { struct cfm *cfm; /* Connectivity Fault Management, if any. */ struct bfd *bfd; /* BFD, if any. */ struct lldp *lldp; /* lldp, if any. */ + uint16_t tunnel_protocol; /* Tunnel underlaying protocol or 0. */ bool may_enable; /* May be enabled in bonds. */ - bool is_tunnel; /* This port is a tunnel. */ bool is_layer3; /* This is a layer 3 port. */ long long int carrier_seq; /* Carrier status changes. */ struct ofport_dpif *peer; /* Peer if patch port. */ @@ -579,7 +579,7 @@ type_run(const char *type) char namebuf[NETDEV_VPORT_NAME_BUFSIZE]; const char *dp_port; - if (!iter->is_tunnel) { + if (!iter->tunnel_protocol) { continue; } @@ -669,7 +669,7 @@ type_run(const char *type) ofport->lldp, ofport->peer, stp_port, ofport->rstp_port, ofport->qdscp, ofport->n_qdscp, ofport->up.pp.config, - ofport->up.pp.state, ofport->is_tunnel, + ofport->up.pp.state, ofport->tunnel_protocol, ofport->may_enable); } xlate_txn_commit(); @@ -1641,6 +1641,7 @@ port_construct(struct ofport *port_) struct ofport_dpif *port = ofport_dpif_cast(port_); struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto); const struct netdev *netdev = port->up.netdev; + const struct netdev_tunnel_config *tnl_cfg; char namebuf[NETDEV_VPORT_NAME_BUFSIZE]; struct dpif_port dpif_port; int error; @@ -1655,7 +1656,7 @@ port_construct(struct ofport *port_) port->stp_state = STP_DISABLED; port->rstp_port = NULL; port->rstp_state = RSTP_DISABLED; - port->is_tunnel = false; + port->tunnel_protocol = 0; port->peer = NULL; port->qdscp = NULL; port->n_qdscp = 0; @@ -1685,11 +1686,12 @@ port_construct(struct ofport *port_) port->odp_port = dpif_port.port_no; - if (netdev_get_tunnel_config(netdev)) { + tnl_cfg = netdev_get_tunnel_config(netdev); + if (tnl_cfg) { atomic_count_inc(&ofproto->backer->tnl_count); tnl_port_add(port, port->up.netdev, port->odp_port, ovs_native_tunneling_is_on(ofproto), namebuf); - port->is_tunnel = true; + port->tunnel_protocol = tnl_cfg->protocol; if (ofproto->ipfix) { dpif_ipfix_add_tunnel_port(ofproto->ipfix, port_, port->odp_port); } @@ -1738,7 +1740,7 @@ port_destruct(struct ofport *port_) * happens when the ofproto is being destroyed, since the caller * assumes that removal of attached ports will happen as part of * destruction. */ - if (!port->is_tunnel) { + if (!port->tunnel_protocol) { dpif_port_del(ofproto->backer->dpif, port->odp_port); } } @@ -1748,17 +1750,17 @@ port_destruct(struct ofport *port_) port->peer = NULL; } - if (port->odp_port != ODPP_NONE && !port->is_tunnel) { + if (port->odp_port != ODPP_NONE && !port->tunnel_protocol) { ovs_rwlock_wrlock(&ofproto->backer->odp_to_ofport_lock); hmap_remove(&ofproto->backer->odp_to_ofport_map, &port->odp_port_node); ovs_rwlock_unlock(&ofproto->backer->odp_to_ofport_lock); } - if (port->is_tunnel) { + if (port->tunnel_protocol) { atomic_count_dec(&ofproto->backer->tnl_count); } - if (port->is_tunnel && ofproto->ipfix) { + if (port->tunnel_protocol && ofproto->ipfix) { dpif_ipfix_del_tunnel_port(ofproto->ipfix, port->odp_port); } @@ -1804,7 +1806,7 @@ port_modified(struct ofport *port_) netdev_vport_get_dpif_port(netdev, namebuf, sizeof namebuf); - if (port->is_tunnel) { + if (port->tunnel_protocol) { struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto); if (tnl_port_reconfigure(port, netdev, port->odp_port, @@ -1893,7 +1895,7 @@ set_ipfix( if (new_di == true) { struct ofport_dpif *ofport; HMAP_FOR_EACH (ofport, up.hmap_node, &ofproto->up.ports) { - if (ofport->is_tunnel == true) { + if (ofport->tunnel_protocol) { dpif_ipfix_add_tunnel_port(di, &ofport->up, ofport->odp_port); } } @@ -3397,7 +3399,7 @@ port_del(struct ofproto *ofproto_, ofp_port_t ofp_port) sset_find_and_delete(&ofproto->ghost_ports, netdev_get_name(ofport->up.netdev)); ofproto->backer->need_revalidate = REV_RECONFIGURE; - if (!ofport->is_tunnel && !netdev_vport_is_patch(ofport->up.netdev)) { + if (!ofport->tunnel_protocol && !netdev_vport_is_patch(ofport->up.netdev)) { error = dpif_port_del(ofproto->backer->dpif, ofport->odp_port); if (!error) { /* The caller is going to close ofport->up.netdev. If this is a -- 1.8.3.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev