summaryrefslogtreecommitdiffstats
path: root/drivers/net/vxlan.c
diff options
context:
space:
mode:
authorJiri Benc2015-12-07 13:04:31 +0100
committerDavid S. Miller2015-12-07 22:31:25 +0100
commit239e944ff532de6e9579b3913d7f76b4f01c7e2f (patch)
tree526afb92723974e700cfcd048e71d09480a2765d /drivers/net/vxlan.c
parentvxlan: move IPv6 outpute route calculation to a function (diff)
downloadkernel-qcow2-linux-239e944ff532de6e9579b3913d7f76b4f01c7e2f.tar.gz
kernel-qcow2-linux-239e944ff532de6e9579b3913d7f76b4f01c7e2f.tar.xz
kernel-qcow2-linux-239e944ff532de6e9579b3913d7f76b4f01c7e2f.zip
vxlan: support ndo_fill_metadata_dst also for IPv6
Fill the metadata correctly even when tunneling over IPv6. Also, check that the provided metadata is of an address family that is supported by the tunnel. Signed-off-by: Jiri Benc <jbenc@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r--drivers/net/vxlan.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 5a38558da157..14cfa4cdf903 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -2419,9 +2419,30 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
vxlan->cfg.port_max, true);
dport = info->key.tp_dst ? : vxlan->cfg.dst_port;
- if (ip_tunnel_info_af(info) == AF_INET)
+ if (ip_tunnel_info_af(info) == AF_INET) {
+ if (!vxlan->vn4_sock)
+ return -EINVAL;
return egress_ipv4_tun_info(dev, skb, info, sport, dport);
- return -EINVAL;
+ } else {
+#if IS_ENABLED(CONFIG_IPV6)
+ struct dst_entry *ndst;
+
+ if (!vxlan->vn6_sock)
+ return -EINVAL;
+ ndst = vxlan6_get_route(vxlan, skb, 0,
+ &info->key.u.ipv6.dst,
+ &info->key.u.ipv6.src);
+ if (IS_ERR(ndst))
+ return PTR_ERR(ndst);
+ dst_release(ndst);
+
+ info->key.tp_src = sport;
+ info->key.tp_dst = dport;
+#else /* !CONFIG_IPV6 */
+ return -EPFNOSUPPORT;
+#endif
+ }
+ return 0;
}
static const struct net_device_ops vxlan_netdev_ops = {