diff options
author | Jarno Rajahalme <jarno.rajahalme@nsn.com> | 2013-05-09 15:24:16 +0300 |
---|---|---|
committer | Ben Pfaff <blp@nicira.com> | 2013-05-10 10:50:06 -0700 |
commit | 0ad90c845b7e82090a846fbe9f927e8d1c84cfc9 (patch) | |
tree | 37cdc628cc8bcb1344075a54de68d1a62620a04c /lib/netdev-vport.c | |
parent | 500d243dad40ff667710aca1d099d97c38e6a62d (diff) |
OpenFlow-level flow-based tunneling support.
Adds tun_src and tun_dst match and set capabilities via new NXM fields
NXM_NX_TUN_IPV4_SRC and NXM_NX_TUN_IPV4_DST. This allows management of
large number of tunnels via the flow tables, without requiring the tunnels
to be pre-configured.
Flow-based tunnels can be configured with options remote_ip=flow and
local_ip=flow. local_ip=flow requires remote_ip=flow. When set, the
tunnel remote IP address and/or local IP address is set from the flow,
instead of the tunnel configuration.
Example:
$ ovs-vsctl add-port br0 gre -- set Interface gre ofport_request=1 type=gre options:remote_ip=flow options:key=flow
$ ovs-ofctl add-flow br0 "in_port=LOCAL actions=set_tunnel:1,set_field:192.168.0.1->tun_dst,output:1"
$ ovs-ofctl add-flow br0 "in_port=1 tun_src=192.168.0.1 tun_id=1 actions=LOCAL"
Signed-off-by: Jarno Rajahalme <jarno.rajahalme@nsn.com>
Signed-off-by: Ben Pfaff <blp@nicira.com>
Diffstat (limited to 'lib/netdev-vport.c')
-rw-r--r-- | lib/netdev-vport.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c index 08169a1b..1bcb34b0 100644 --- a/lib/netdev-vport.c +++ b/lib/netdev-vport.c @@ -325,7 +325,10 @@ set_tunnel_config(struct netdev_dev *dev_, const struct smap *args) SMAP_FOR_EACH (node, args) { if (!strcmp(node->key, "remote_ip")) { struct in_addr in_addr; - if (lookup_ip(node->value, &in_addr)) { + if (!strcmp(node->value, "flow")) { + tnl_cfg.ip_dst_flow = true; + tnl_cfg.ip_dst = htonl(0); + } else if (lookup_ip(node->value, &in_addr)) { VLOG_WARN("%s: bad %s 'remote_ip'", name, type); } else if (ip_is_multicast(in_addr.s_addr)) { VLOG_WARN("%s: multicast remote_ip="IP_FMT" not allowed", @@ -336,7 +339,10 @@ set_tunnel_config(struct netdev_dev *dev_, const struct smap *args) } } else if (!strcmp(node->key, "local_ip")) { struct in_addr in_addr; - if (lookup_ip(node->value, &in_addr)) { + if (!strcmp(node->value, "flow")) { + tnl_cfg.ip_src_flow = true; + tnl_cfg.ip_src = htonl(0); + } else if (lookup_ip(node->value, &in_addr)) { VLOG_WARN("%s: bad %s 'local_ip'", name, type); } else { tnl_cfg.ip_src = in_addr.s_addr; @@ -443,11 +449,16 @@ set_tunnel_config(struct netdev_dev *dev_, const struct smap *args) } } - if (!tnl_cfg.ip_dst) { + if (!tnl_cfg.ip_dst && !tnl_cfg.ip_dst_flow) { VLOG_ERR("%s: %s type requires valid 'remote_ip' argument", name, type); return EINVAL; } + if (tnl_cfg.ip_src_flow && !tnl_cfg.ip_dst_flow) { + VLOG_ERR("%s: %s type requires 'remote_ip=flow' with 'local_ip=flow'", + name, type); + return EINVAL; + } if (!tnl_cfg.ttl) { tnl_cfg.ttl = DEFAULT_TTL; } @@ -474,10 +485,14 @@ get_tunnel_config(struct netdev_dev *dev, struct smap *args) if (tnl_cfg->ip_dst) { smap_add_format(args, "remote_ip", IP_FMT, IP_ARGS(tnl_cfg->ip_dst)); + } else if (tnl_cfg->ip_dst_flow) { + smap_add(args, "remote_ip", "flow"); } if (tnl_cfg->ip_src) { smap_add_format(args, "local_ip", IP_FMT, IP_ARGS(tnl_cfg->ip_src)); + } else if (tnl_cfg->ip_src_flow) { + smap_add(args, "local_ip", "flow"); } if (tnl_cfg->in_key_flow && tnl_cfg->out_key_flow) { |