Commit 8f350437 authored by David S. Miller's avatar David S. Miller

Merge branch 'vxlan-ipv4-ipv6'

Jiri Benc says:

====================
vxlan: support both IPv4 and IPv6 sockets

Note: this needs net merged into net-next in order to apply.

It's currently not easy enough to work with metadata based vxlan tunnels. In
particular, it's necessary to create separate network interfaces for IPv4
and IPv6 tunneling. Assigning an IPv6 address to an IPv4 interface is
allowed yet won't do what's expected. With route based tunneling, one has to
pay attention to use the vxlan interface opened with the correct family.
Other users of this (openvswitch) would need to always create two vxlan
interfaces.

Furthermore, there's no sane API for creating an IPv6 vxlan metadata based
interface.

This patchset simplifies this by opening both IPv4 and IPv6 socket if the
vxlan interface has the metadata flag (IFLA_VXLAN_COLLECT_METADATA) set.
Assignment of addresses etc. works as expected after this.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 8b7a7048 b1be00a6
This diff is collapsed.
...@@ -152,7 +152,10 @@ struct vxlan_config { ...@@ -152,7 +152,10 @@ struct vxlan_config {
struct vxlan_dev { struct vxlan_dev {
struct hlist_node hlist; /* vni hash table */ struct hlist_node hlist; /* vni hash table */
struct list_head next; /* vxlan's per namespace list */ struct list_head next; /* vxlan's per namespace list */
struct vxlan_sock *vn_sock; /* listening socket */ struct vxlan_sock *vn4_sock; /* listening socket for IPv4 */
#if IS_ENABLED(CONFIG_IPV6)
struct vxlan_sock *vn6_sock; /* listening socket for IPv6 */
#endif
struct net_device *dev; struct net_device *dev;
struct net *net; /* netns for packet i/o */ struct net *net; /* netns for packet i/o */
struct vxlan_rdst default_dst; /* default destination */ struct vxlan_rdst default_dst; /* default destination */
...@@ -195,9 +198,14 @@ struct vxlan_dev { ...@@ -195,9 +198,14 @@ struct vxlan_dev {
struct net_device *vxlan_dev_create(struct net *net, const char *name, struct net_device *vxlan_dev_create(struct net *net, const char *name,
u8 name_assign_type, struct vxlan_config *conf); u8 name_assign_type, struct vxlan_config *conf);
static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan) static inline __be16 vxlan_dev_dst_port(struct vxlan_dev *vxlan,
unsigned short family)
{ {
return inet_sk(vxlan->vn_sock->sock->sk)->inet_sport; #if IS_ENABLED(CONFIG_IPV6)
if (family == AF_INET6)
return inet_sk(vxlan->vn6_sock->sock->sk)->inet_sport;
#endif
return inet_sk(vxlan->vn4_sock->sock->sk)->inet_sport;
} }
static inline netdev_features_t vxlan_features_check(struct sk_buff *skb, static inline netdev_features_t vxlan_features_check(struct sk_buff *skb,
......
...@@ -151,7 +151,8 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb, ...@@ -151,7 +151,8 @@ static int vxlan_get_egress_tun_info(struct vport *vport, struct sk_buff *skb,
{ {
struct vxlan_dev *vxlan = netdev_priv(vport->dev); struct vxlan_dev *vxlan = netdev_priv(vport->dev);
struct net *net = ovs_dp_get_net(vport->dp); struct net *net = ovs_dp_get_net(vport->dp);
__be16 dst_port = vxlan_dev_dst_port(vxlan); unsigned short family = ip_tunnel_info_af(upcall->egress_tun_info);
__be16 dst_port = vxlan_dev_dst_port(vxlan, family);
__be16 src_port; __be16 src_port;
int port_min; int port_min;
int port_max; int port_max;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment