Also add a new 'protocol' field that holds the outer protocol. Signed-off-by: Jiri Benc <jb...@redhat.com> --- ofproto/tunnel.c | 66 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 13 deletions(-)
diff --git a/ofproto/tunnel.c b/ofproto/tunnel.c index ccef40a59668..116ba061bb6c 100644 --- a/ofproto/tunnel.c +++ b/ofproto/tunnel.c @@ -49,8 +49,11 @@ struct tnl_match { ovs_be64 in_key; ovs_be32 ip_src; ovs_be32 ip_dst; + struct in6_addr ipv6_src; + struct in6_addr ipv6_dst; odp_port_t odp_port; uint32_t pkt_mark; + uint16_t protocol; bool in_key_flow; bool ip_src_flow; bool ip_dst_flow; @@ -163,6 +166,9 @@ tnl_port_add__(const struct ofport_dpif *ofport, const struct netdev *netdev, tnl_port->match.in_key = cfg->in_key; tnl_port->match.ip_src = cfg->ip_src; tnl_port->match.ip_dst = cfg->ip_dst; + tnl_port->match.ipv6_src = cfg->ipv6_src; + tnl_port->match.ipv6_dst = cfg->ipv6_dst; + tnl_port->match.protocol = cfg->protocol; tnl_port->match.ip_src_flow = cfg->ip_src_flow; tnl_port->match.ip_dst_flow = cfg->ip_dst_flow; tnl_port->match.pkt_mark = cfg->ipsec ? IPSEC_MARK : 0; @@ -423,10 +429,18 @@ tnl_port_send(const struct ofport_dpif *ofport, struct flow *flow, } if (!cfg->ip_src_flow) { - flow->tunnel.ip_src = tnl_port->match.ip_src; + if (cfg->protocol == ETH_TYPE_IPV6) { + flow->tunnel.ipv6_src = tnl_port->match.ipv6_src; + } else { + flow->tunnel.ip_src = tnl_port->match.ip_src; + } } if (!cfg->ip_dst_flow) { - flow->tunnel.ip_dst = tnl_port->match.ip_dst; + if (cfg->protocol == ETH_TYPE_IPV6) { + flow->tunnel.ipv6_dst = tnl_port->match.ipv6_dst; + } else { + flow->tunnel.ip_dst = tnl_port->match.ip_dst; + } } flow->pkt_mark = tnl_port->match.pkt_mark; @@ -526,8 +540,10 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock) enum ip_src_type ip_src; int in_key_flow; int ip_dst_flow; + bool ipv6; int i; + ipv6 = ipv6_addr_is_set(&flow->tunnel.ipv6_dst); i = 0; for (in_key_flow = 0; in_key_flow < 2; in_key_flow++) { for (ip_dst_flow = 0; ip_dst_flow < 2; ip_dst_flow++) { @@ -546,12 +562,23 @@ tnl_find(const struct flow *flow) OVS_REQ_RDLOCK(rwlock) * here as a description of how to treat received * packets. */ match.in_key = in_key_flow ? 0 : flow->tunnel.tun_id; - match.ip_src = (ip_src == IP_SRC_CFG - ? flow->tunnel.ip_dst - : 0); - match.ip_dst = ip_dst_flow ? 0 : flow->tunnel.ip_src; + if (ip_src == IP_SRC_CFG) { + if (!ipv6) { + match.ip_src = flow->tunnel.ip_dst; + } else { + match.ipv6_src = flow->tunnel.ipv6_dst; + } + } + if (!ip_dst_flow) { + if (!ipv6) { + match.ip_dst = flow->tunnel.ip_src; + } else { + match.ipv6_dst = flow->tunnel.ipv6_src; + } + } match.odp_port = flow->in_port.odp_port; match.pkt_mark = flow->pkt_mark; + match.protocol = ipv6 ? ETH_TYPE_IPV6 : ETH_TYPE_IP; match.in_key_flow = in_key_flow; match.ip_dst_flow = ip_dst_flow; match.ip_src_flow = ip_src == IP_SRC_FLOW; @@ -578,7 +605,7 @@ tnl_match_map(const struct tnl_match *m) enum ip_src_type ip_src; ip_src = (m->ip_src_flow ? IP_SRC_FLOW - : m->ip_src ? IP_SRC_CFG + : (m->ip_src || ipv6_addr_is_set(&m->ipv6_src)) ? IP_SRC_CFG : IP_SRC_ANY); return &tnl_match_maps[6 * m->in_key_flow + 3 * m->ip_dst_flow + ip_src]; @@ -588,13 +615,26 @@ static void tnl_match_fmt(const struct tnl_match *match, struct ds *ds) OVS_REQ_RDLOCK(rwlock) { - if (!match->ip_dst_flow) { - ds_put_format(ds, IP_FMT"->"IP_FMT, IP_ARGS(match->ip_src), - IP_ARGS(match->ip_dst)); - } else if (!match->ip_src_flow) { - ds_put_format(ds, IP_FMT"->flow", IP_ARGS(match->ip_src)); + if (match->protocol == ETH_TYPE_IP) { + if (!match->ip_dst_flow) { + ds_put_format(ds, IP_FMT"->"IP_FMT, IP_ARGS(match->ip_src), + IP_ARGS(match->ip_dst)); + } else if (!match->ip_src_flow) { + ds_put_format(ds, IP_FMT"->flow", IP_ARGS(match->ip_src)); + } else { + ds_put_cstr(ds, "flow->flow"); + } } else { - ds_put_cstr(ds, "flow->flow"); + if (!match->ip_dst_flow) { + ds_put_in6_addr(ds, &match->ipv6_src); + ds_put_cstr(ds, "->"); + ds_put_in6_addr(ds, &match->ipv6_dst); + } else if (!match->ip_src_flow) { + ds_put_in6_addr(ds, &match->ipv6_src); + ds_put_cstr(ds, "->flow6"); + } else { + ds_put_cstr(ds, "flow6->flow6"); + } } if (match->in_key_flow) { -- 1.8.3.1 _______________________________________________ dev mailing list dev@openvswitch.org http://openvswitch.org/mailman/listinfo/dev