aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/vxlan.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2016-01-12 05:01:12 -0500
committerThomas Gleixner <tglx@linutronix.de>2016-01-12 05:01:12 -0500
commit1f16f116b01c110db20ab808562c8b8bc3ee3d6e (patch)
tree44db563f64cf5f8d62af8f99a61e2b248c44ea3a /drivers/net/vxlan.c
parent03724ac3d48f8f0e3caf1d30fa134f8fd96c94e2 (diff)
parentf9eccf24615672896dc13251410c3f2f33a14f95 (diff)
Merge branches 'clockevents/4.4-fixes' and 'clockevents/4.5-fixes' of http://git.linaro.org/people/daniel.lezcano/linux into timers/urgent
Pull in fixes from Daniel Lezcano: - Fix the vt8500 timer leading to a system lock up when dealing with too small delta (Roman Volkov) - Select the CLKSRC_MMIO when the fsl_ftm_timer is enabled with COMPILE_TEST (Daniel Lezcano) - Prevent to compile timers using the 'iomem' API when the architecture has not HAS_IOMEM set (Richard Weinberger)
Diffstat (limited to 'drivers/net/vxlan.c')
-rw-r--r--drivers/net/vxlan.c75
1 files changed, 59 insertions, 16 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 6369a5734d4c..ba363cedef80 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1158,7 +1158,6 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
1158 struct pcpu_sw_netstats *stats; 1158 struct pcpu_sw_netstats *stats;
1159 union vxlan_addr saddr; 1159 union vxlan_addr saddr;
1160 int err = 0; 1160 int err = 0;
1161 union vxlan_addr *remote_ip;
1162 1161
1163 /* For flow based devices, map all packets to VNI 0 */ 1162 /* For flow based devices, map all packets to VNI 0 */
1164 if (vs->flags & VXLAN_F_COLLECT_METADATA) 1163 if (vs->flags & VXLAN_F_COLLECT_METADATA)
@@ -1169,7 +1168,6 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
1169 if (!vxlan) 1168 if (!vxlan)
1170 goto drop; 1169 goto drop;
1171 1170
1172 remote_ip = &vxlan->default_dst.remote_ip;
1173 skb_reset_mac_header(skb); 1171 skb_reset_mac_header(skb);
1174 skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev))); 1172 skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev)));
1175 skb->protocol = eth_type_trans(skb, vxlan->dev); 1173 skb->protocol = eth_type_trans(skb, vxlan->dev);
@@ -1179,8 +1177,8 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
1179 if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr)) 1177 if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
1180 goto drop; 1178 goto drop;
1181 1179
1182 /* Re-examine inner Ethernet packet */ 1180 /* Get data from the outer IP header */
1183 if (remote_ip->sa.sa_family == AF_INET) { 1181 if (vxlan_get_sk_family(vs) == AF_INET) {
1184 oip = ip_hdr(skb); 1182 oip = ip_hdr(skb);
1185 saddr.sin.sin_addr.s_addr = oip->saddr; 1183 saddr.sin.sin_addr.s_addr = oip->saddr;
1186 saddr.sa.sa_family = AF_INET; 1184 saddr.sa.sa_family = AF_INET;
@@ -1848,6 +1846,34 @@ static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk
1848 !(vxflags & VXLAN_F_UDP_CSUM)); 1846 !(vxflags & VXLAN_F_UDP_CSUM));
1849} 1847}
1850 1848
1849#if IS_ENABLED(CONFIG_IPV6)
1850static struct dst_entry *vxlan6_get_route(struct vxlan_dev *vxlan,
1851 struct sk_buff *skb, int oif,
1852 const struct in6_addr *daddr,
1853 struct in6_addr *saddr)
1854{
1855 struct dst_entry *ndst;
1856 struct flowi6 fl6;
1857 int err;
1858
1859 memset(&fl6, 0, sizeof(fl6));
1860 fl6.flowi6_oif = oif;
1861 fl6.daddr = *daddr;
1862 fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr;
1863 fl6.flowi6_mark = skb->mark;
1864 fl6.flowi6_proto = IPPROTO_UDP;
1865
1866 err = ipv6_stub->ipv6_dst_lookup(vxlan->net,
1867 vxlan->vn6_sock->sock->sk,
1868 &ndst, &fl6);
1869 if (err < 0)
1870 return ERR_PTR(err);
1871
1872 *saddr = fl6.saddr;
1873 return ndst;
1874}
1875#endif
1876
1851/* Bypass encapsulation if the destination is local */ 1877/* Bypass encapsulation if the destination is local */
1852static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan, 1878static void vxlan_encap_bypass(struct sk_buff *skb, struct vxlan_dev *src_vxlan,
1853 struct vxlan_dev *dst_vxlan) 1879 struct vxlan_dev *dst_vxlan)
@@ -2035,21 +2061,17 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2035#if IS_ENABLED(CONFIG_IPV6) 2061#if IS_ENABLED(CONFIG_IPV6)
2036 } else { 2062 } else {
2037 struct dst_entry *ndst; 2063 struct dst_entry *ndst;
2038 struct flowi6 fl6; 2064 struct in6_addr saddr;
2039 u32 rt6i_flags; 2065 u32 rt6i_flags;
2040 2066
2041 if (!vxlan->vn6_sock) 2067 if (!vxlan->vn6_sock)
2042 goto drop; 2068 goto drop;
2043 sk = vxlan->vn6_sock->sock->sk; 2069 sk = vxlan->vn6_sock->sock->sk;
2044 2070
2045 memset(&fl6, 0, sizeof(fl6)); 2071 ndst = vxlan6_get_route(vxlan, skb,
2046 fl6.flowi6_oif = rdst ? rdst->remote_ifindex : 0; 2072 rdst ? rdst->remote_ifindex : 0,
2047 fl6.daddr = dst->sin6.sin6_addr; 2073 &dst->sin6.sin6_addr, &saddr);
2048 fl6.saddr = vxlan->cfg.saddr.sin6.sin6_addr; 2074 if (IS_ERR(ndst)) {
2049 fl6.flowi6_mark = skb->mark;
2050 fl6.flowi6_proto = IPPROTO_UDP;
2051
2052 if (ipv6_stub->ipv6_dst_lookup(vxlan->net, sk, &ndst, &fl6)) {
2053 netdev_dbg(dev, "no route to %pI6\n", 2075 netdev_dbg(dev, "no route to %pI6\n",
2054 &dst->sin6.sin6_addr); 2076 &dst->sin6.sin6_addr);
2055 dev->stats.tx_carrier_errors++; 2077 dev->stats.tx_carrier_errors++;
@@ -2081,7 +2103,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
2081 } 2103 }
2082 2104
2083 ttl = ttl ? : ip6_dst_hoplimit(ndst); 2105 ttl = ttl ? : ip6_dst_hoplimit(ndst);
2084 err = vxlan6_xmit_skb(ndst, sk, skb, dev, &fl6.saddr, &fl6.daddr, 2106 err = vxlan6_xmit_skb(ndst, sk, skb, dev, &saddr, &dst->sin6.sin6_addr,
2085 0, ttl, src_port, dst_port, htonl(vni << 8), md, 2107 0, ttl, src_port, dst_port, htonl(vni << 8), md,
2086 !net_eq(vxlan->net, dev_net(vxlan->dev)), 2108 !net_eq(vxlan->net, dev_net(vxlan->dev)),
2087 flags); 2109 flags);
@@ -2395,9 +2417,30 @@ static int vxlan_fill_metadata_dst(struct net_device *dev, struct sk_buff *skb)
2395 vxlan->cfg.port_max, true); 2417 vxlan->cfg.port_max, true);
2396 dport = info->key.tp_dst ? : vxlan->cfg.dst_port; 2418 dport = info->key.tp_dst ? : vxlan->cfg.dst_port;
2397 2419
2398 if (ip_tunnel_info_af(info) == AF_INET) 2420 if (ip_tunnel_info_af(info) == AF_INET) {
2421 if (!vxlan->vn4_sock)
2422 return -EINVAL;
2399 return egress_ipv4_tun_info(dev, skb, info, sport, dport); 2423 return egress_ipv4_tun_info(dev, skb, info, sport, dport);
2400 return -EINVAL; 2424 } else {
2425#if IS_ENABLED(CONFIG_IPV6)
2426 struct dst_entry *ndst;
2427
2428 if (!vxlan->vn6_sock)
2429 return -EINVAL;
2430 ndst = vxlan6_get_route(vxlan, skb, 0,
2431 &info->key.u.ipv6.dst,
2432 &info->key.u.ipv6.src);
2433 if (IS_ERR(ndst))
2434 return PTR_ERR(ndst);
2435 dst_release(ndst);
2436
2437 info->key.tp_src = sport;
2438 info->key.tp_dst = dport;
2439#else /* !CONFIG_IPV6 */
2440 return -EPFNOSUPPORT;
2441#endif
2442 }
2443 return 0;
2401} 2444}
2402 2445
2403static const struct net_device_ops vxlan_netdev_ops = { 2446static const struct net_device_ops vxlan_netdev_ops = {