aboutsummaryrefslogtreecommitdiffstats
path: root/net/openvswitch
diff options
context:
space:
mode:
authorwenxu <wenxu@ucloud.cn>2019-03-28 00:43:23 -0400
committerDavid S. Miller <davem@davemloft.net>2019-03-29 16:29:15 -0400
commit18b6f717483a835fb98de9f0df6c724df9324e78 (patch)
tree8efa350074253df8c892e921dd2c8d15024f9102 /net/openvswitch
parenteb70a1ae2339769156f8ecddd7f6cd59ac994888 (diff)
openvswitch: Make metadata_dst tunnel work in IP_TUNNEL_INFO_BRIDGE mode
There is currently no support for the multicast/broadcast aspects of VXLAN in ovs. In the datapath flow the tun_dst must specific. But in the IP_TUNNEL_INFO_BRIDGE mode the tun_dst can not be specific. And the packet can forward through the fdb table of vxlan devcice. In this mode the broadcast/multicast packet can be sent through the following ways in ovs. ovs-vsctl add-port br0 vxlan -- set in vxlan type=vxlan \ options:key=1000 options:remote_ip=flow ovs-ofctl add-flow br0 in_port=LOCAL,dl_dst=ff:ff:ff:ff:ff:ff, \ action=output:vxlan bridge fdb append ff:ff:ff:ff:ff:ff dev vxlan_sys_4789 dst 172.168.0.1 \ src_vni 1000 vni 1000 self bridge fdb append ff:ff:ff:ff:ff:ff dev vxlan_sys_4789 dst 172.168.0.2 \ src_vni 1000 vni 1000 self Signed-off-by: wenxu <wenxu@ucloud.cn> Acked-by: Pravin B Shelar <pshelar@ovn.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/openvswitch')
-rw-r--r--net/openvswitch/flow_netlink.c46
1 files changed, 36 insertions, 10 deletions
diff --git a/net/openvswitch/flow_netlink.c b/net/openvswitch/flow_netlink.c
index b7543700db87..bd019058fc6f 100644
--- a/net/openvswitch/flow_netlink.c
+++ b/net/openvswitch/flow_netlink.c
@@ -404,6 +404,7 @@ static const struct ovs_len_tbl ovs_tunnel_key_lens[OVS_TUNNEL_KEY_ATTR_MAX + 1]
404 [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) }, 404 [OVS_TUNNEL_KEY_ATTR_IPV6_SRC] = { .len = sizeof(struct in6_addr) },
405 [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) }, 405 [OVS_TUNNEL_KEY_ATTR_IPV6_DST] = { .len = sizeof(struct in6_addr) },
406 [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = OVS_ATTR_VARIABLE }, 406 [OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS] = { .len = OVS_ATTR_VARIABLE },
407 [OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE] = { .len = 0 },
407}; 408};
408 409
409static const struct ovs_len_tbl 410static const struct ovs_len_tbl
@@ -667,6 +668,7 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
667 bool log) 668 bool log)
668{ 669{
669 bool ttl = false, ipv4 = false, ipv6 = false; 670 bool ttl = false, ipv4 = false, ipv6 = false;
671 bool info_bridge_mode = false;
670 __be16 tun_flags = 0; 672 __be16 tun_flags = 0;
671 int opts_type = 0; 673 int opts_type = 0;
672 struct nlattr *a; 674 struct nlattr *a;
@@ -783,6 +785,10 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
783 tun_flags |= TUNNEL_ERSPAN_OPT; 785 tun_flags |= TUNNEL_ERSPAN_OPT;
784 opts_type = type; 786 opts_type = type;
785 break; 787 break;
788 case OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE:
789 info_bridge_mode = true;
790 ipv4 = true;
791 break;
786 default: 792 default:
787 OVS_NLERR(log, "Unknown IP tunnel attribute %d", 793 OVS_NLERR(log, "Unknown IP tunnel attribute %d",
788 type); 794 type);
@@ -813,16 +819,29 @@ static int ip_tun_from_nlattr(const struct nlattr *attr,
813 OVS_NLERR(log, "IP tunnel dst address not specified"); 819 OVS_NLERR(log, "IP tunnel dst address not specified");
814 return -EINVAL; 820 return -EINVAL;
815 } 821 }
816 if (ipv4 && !match->key->tun_key.u.ipv4.dst) { 822 if (ipv4) {
817 OVS_NLERR(log, "IPv4 tunnel dst address is zero"); 823 if (info_bridge_mode) {
818 return -EINVAL; 824 if (match->key->tun_key.u.ipv4.src ||
825 match->key->tun_key.u.ipv4.dst ||
826 match->key->tun_key.tp_src ||
827 match->key->tun_key.tp_dst ||
828 match->key->tun_key.ttl ||
829 match->key->tun_key.tos ||
830 tun_flags & ~TUNNEL_KEY) {
831 OVS_NLERR(log, "IPv4 tun info is not correct");
832 return -EINVAL;
833 }
834 } else if (!match->key->tun_key.u.ipv4.dst) {
835 OVS_NLERR(log, "IPv4 tunnel dst address is zero");
836 return -EINVAL;
837 }
819 } 838 }
820 if (ipv6 && ipv6_addr_any(&match->key->tun_key.u.ipv6.dst)) { 839 if (ipv6 && ipv6_addr_any(&match->key->tun_key.u.ipv6.dst)) {
821 OVS_NLERR(log, "IPv6 tunnel dst address is zero"); 840 OVS_NLERR(log, "IPv6 tunnel dst address is zero");
822 return -EINVAL; 841 return -EINVAL;
823 } 842 }
824 843
825 if (!ttl) { 844 if (!ttl && !info_bridge_mode) {
826 OVS_NLERR(log, "IP tunnel TTL not specified."); 845 OVS_NLERR(log, "IP tunnel TTL not specified.");
827 return -EINVAL; 846 return -EINVAL;
828 } 847 }
@@ -851,12 +870,17 @@ static int vxlan_opt_to_nlattr(struct sk_buff *skb,
851static int __ip_tun_to_nlattr(struct sk_buff *skb, 870static int __ip_tun_to_nlattr(struct sk_buff *skb,
852 const struct ip_tunnel_key *output, 871 const struct ip_tunnel_key *output,
853 const void *tun_opts, int swkey_tun_opts_len, 872 const void *tun_opts, int swkey_tun_opts_len,
854 unsigned short tun_proto) 873 unsigned short tun_proto, u8 mode)
855{ 874{
856 if (output->tun_flags & TUNNEL_KEY && 875 if (output->tun_flags & TUNNEL_KEY &&
857 nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id, 876 nla_put_be64(skb, OVS_TUNNEL_KEY_ATTR_ID, output->tun_id,
858 OVS_TUNNEL_KEY_ATTR_PAD)) 877 OVS_TUNNEL_KEY_ATTR_PAD))
859 return -EMSGSIZE; 878 return -EMSGSIZE;
879
880 if (mode & IP_TUNNEL_INFO_BRIDGE)
881 return nla_put_flag(skb, OVS_TUNNEL_KEY_ATTR_IPV4_INFO_BRIDGE)
882 ? -EMSGSIZE : 0;
883
860 switch (tun_proto) { 884 switch (tun_proto) {
861 case AF_INET: 885 case AF_INET:
862 if (output->u.ipv4.src && 886 if (output->u.ipv4.src &&
@@ -919,7 +943,7 @@ static int __ip_tun_to_nlattr(struct sk_buff *skb,
919static int ip_tun_to_nlattr(struct sk_buff *skb, 943static int ip_tun_to_nlattr(struct sk_buff *skb,
920 const struct ip_tunnel_key *output, 944 const struct ip_tunnel_key *output,
921 const void *tun_opts, int swkey_tun_opts_len, 945 const void *tun_opts, int swkey_tun_opts_len,
922 unsigned short tun_proto) 946 unsigned short tun_proto, u8 mode)
923{ 947{
924 struct nlattr *nla; 948 struct nlattr *nla;
925 int err; 949 int err;
@@ -929,7 +953,7 @@ static int ip_tun_to_nlattr(struct sk_buff *skb,
929 return -EMSGSIZE; 953 return -EMSGSIZE;
930 954
931 err = __ip_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len, 955 err = __ip_tun_to_nlattr(skb, output, tun_opts, swkey_tun_opts_len,
932 tun_proto); 956 tun_proto, mode);
933 if (err) 957 if (err)
934 return err; 958 return err;
935 959
@@ -943,7 +967,7 @@ int ovs_nla_put_tunnel_info(struct sk_buff *skb,
943 return __ip_tun_to_nlattr(skb, &tun_info->key, 967 return __ip_tun_to_nlattr(skb, &tun_info->key,
944 ip_tunnel_info_opts(tun_info), 968 ip_tunnel_info_opts(tun_info),
945 tun_info->options_len, 969 tun_info->options_len,
946 ip_tunnel_info_af(tun_info)); 970 ip_tunnel_info_af(tun_info), tun_info->mode);
947} 971}
948 972
949static int encode_vlan_from_nlattrs(struct sw_flow_match *match, 973static int encode_vlan_from_nlattrs(struct sw_flow_match *match,
@@ -1981,7 +2005,7 @@ static int __ovs_nla_put_key(const struct sw_flow_key *swkey,
1981 opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len); 2005 opts = TUN_METADATA_OPTS(output, swkey->tun_opts_len);
1982 2006
1983 if (ip_tun_to_nlattr(skb, &output->tun_key, opts, 2007 if (ip_tun_to_nlattr(skb, &output->tun_key, opts,
1984 swkey->tun_opts_len, swkey->tun_proto)) 2008 swkey->tun_opts_len, swkey->tun_proto, 0))
1985 goto nla_put_failure; 2009 goto nla_put_failure;
1986 } 2010 }
1987 2011
@@ -2606,6 +2630,8 @@ static int validate_and_copy_set_tun(const struct nlattr *attr,
2606 tun_info->mode = IP_TUNNEL_INFO_TX; 2630 tun_info->mode = IP_TUNNEL_INFO_TX;
2607 if (key.tun_proto == AF_INET6) 2631 if (key.tun_proto == AF_INET6)
2608 tun_info->mode |= IP_TUNNEL_INFO_IPV6; 2632 tun_info->mode |= IP_TUNNEL_INFO_IPV6;
2633 else if (key.tun_proto == AF_INET && key.tun_key.u.ipv4.dst == 0)
2634 tun_info->mode |= IP_TUNNEL_INFO_BRIDGE;
2609 tun_info->key = key.tun_key; 2635 tun_info->key = key.tun_key;
2610 2636
2611 /* We need to store the options in the action itself since 2637 /* We need to store the options in the action itself since
@@ -3367,7 +3393,7 @@ static int set_action_to_attr(const struct nlattr *a, struct sk_buff *skb)
3367 err = ip_tun_to_nlattr(skb, &tun_info->key, 3393 err = ip_tun_to_nlattr(skb, &tun_info->key,
3368 ip_tunnel_info_opts(tun_info), 3394 ip_tunnel_info_opts(tun_info),
3369 tun_info->options_len, 3395 tun_info->options_len,
3370 ip_tunnel_info_af(tun_info)); 3396 ip_tunnel_info_af(tun_info), tun_info->mode);
3371 if (err) 3397 if (err)
3372 return err; 3398 return err;
3373 nla_nest_end(skb, start); 3399 nla_nest_end(skb, start);