#include "seq.h"
#include "smap.h"
#include "socket-util.h"
-#include "tnl-arp-cache.h"
#include "tnl-ports.h"
#include "tunnel.h"
#include "openvswitch/vlog.h"
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;
bool in_key_flow;
tnl_port->change_seq = netdev_get_change_seq(tnl_port->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.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;
{
if (tnl_port_should_receive(flow)) {
wc->masks.tunnel.tun_id = OVS_BE64_MAX;
- wc->masks.tunnel.ip_src = OVS_BE32_MAX;
- wc->masks.tunnel.ip_dst = OVS_BE32_MAX;
+ if (flow->tunnel.ip_dst) {
+ wc->masks.tunnel.ip_src = OVS_BE32_MAX;
+ wc->masks.tunnel.ip_dst = OVS_BE32_MAX;
+ } else {
+ wc->masks.tunnel.ipv6_src = in6addr_exact;
+ wc->masks.tunnel.ipv6_dst = in6addr_exact;
+ }
wc->masks.tunnel.flags = (FLOW_TNL_F_DONT_FRAGMENT |
FLOW_TNL_F_CSUM |
FLOW_TNL_F_KEY);
}
if (!cfg->ip_src_flow) {
- flow->tunnel.ip_src = tnl_port->match.ip_src;
+ flow->tunnel.ip_src = in6_addr_get_mapped_ipv4(&tnl_port->match.ipv6_src);
+ if (!flow->tunnel.ip_src) {
+ flow->tunnel.ipv6_src = tnl_port->match.ipv6_src;
+ }
}
if (!cfg->ip_dst_flow) {
- flow->tunnel.ip_dst = tnl_port->match.ip_dst;
+ flow->tunnel.ip_dst = in6_addr_get_mapped_ipv4(&tnl_port->match.ipv6_dst);
+ if (!flow->tunnel.ip_dst) {
+ flow->tunnel.ipv6_dst = tnl_port->match.ipv6_dst;
+ }
}
flow->pkt_mark = tnl_port->match.pkt_mark;
* 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) {
+ match.ipv6_src = flow_tnl_dst(&flow->tunnel);
+ }
+ if (!ip_dst_flow) {
+ match.ipv6_dst = flow_tnl_src(&flow->tunnel);
+ }
match.odp_port = flow->in_port.odp_port;
match.pkt_mark = flow->pkt_mark;
match.in_key_flow = in_key_flow;
enum ip_src_type ip_src;
ip_src = (m->ip_src_flow ? IP_SRC_FLOW
- : m->ip_src ? IP_SRC_CFG
+ : 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];
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));
+ ipv6_format_mapped(&match->ipv6_src, ds);
+ ds_put_cstr(ds, "->");
+ ipv6_format_mapped(&match->ipv6_dst, ds);
} else if (!match->ip_src_flow) {
- ds_put_format(ds, IP_FMT"->flow", IP_ARGS(match->ip_src));
+ ipv6_format_mapped(&match->ipv6_src, ds);
+ ds_put_cstr(ds, "->flow");
} else {
ds_put_cstr(ds, "flow->flow");
}
int
tnl_port_build_header(const struct ofport_dpif *ofport,
const struct flow *tnl_flow,
- uint8_t dmac[ETH_ADDR_LEN],
- uint8_t smac[ETH_ADDR_LEN],
+ const struct eth_addr dmac,
+ const struct eth_addr smac,
ovs_be32 ip_src, struct ovs_action_push_tnl *data)
{
struct tnl_port *tnl_port;
memset(data->header, 0, sizeof data->header);
eth = (struct eth_header *)data->header;
- memcpy(eth->eth_dst, dmac, ETH_ADDR_LEN);
- memcpy(eth->eth_src, smac, ETH_ADDR_LEN);
+ eth->eth_dst = dmac;
+ eth->eth_src = smac;
eth->eth_type = htons(ETH_TYPE_IP);
l3 = (eth + 1);