]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/net/vxlan.c
ixgbevf: Fix handling of NAPI budget when multiple queues are enabled per vector
[karo-tx-linux.git] / drivers / net / vxlan.c
index 5a38558da15761f20e3502f4ce165d38e348542a..fecf7b6c732e96a76d2dd0b1ff7433a76ab2e37d 100644 (file)
@@ -1158,7 +1158,6 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
        struct pcpu_sw_netstats *stats;
        union vxlan_addr saddr;
        int err = 0;
-       union vxlan_addr *remote_ip;
 
        /* For flow based devices, map all packets to VNI 0 */
        if (vs->flags & VXLAN_F_COLLECT_METADATA)
@@ -1169,7 +1168,6 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
        if (!vxlan)
                goto drop;
 
-       remote_ip = &vxlan->default_dst.remote_ip;
        skb_reset_mac_header(skb);
        skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev)));
        skb->protocol = eth_type_trans(skb, vxlan->dev);
@@ -1179,8 +1177,8 @@ static void vxlan_rcv(struct vxlan_sock *vs, struct sk_buff *skb,
        if (ether_addr_equal(eth_hdr(skb)->h_source, vxlan->dev->dev_addr))
                goto drop;
 
-       /* Re-examine inner Ethernet packet */
-       if (remote_ip->sa.sa_family == AF_INET) {
+       /* Get data from the outer IP header */
+       if (vxlan_get_sk_family(vs) == AF_INET) {
                oip = ip_hdr(skb);
                saddr.sin.sin_addr.s_addr = oip->saddr;
                saddr.sa.sa_family = AF_INET;
@@ -1843,9 +1841,10 @@ static int vxlan_xmit_skb(struct rtable *rt, struct sock *sk, struct sk_buff *sk
 
        skb_set_inner_protocol(skb, htons(ETH_P_TEB));
 
-       return udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos,
-                                  ttl, df, src_port, dst_port, xnet,
-                                  !(vxflags & VXLAN_F_UDP_CSUM));
+       udp_tunnel_xmit_skb(rt, sk, skb, src, dst, tos, ttl, df,
+                           src_port, dst_port, xnet,
+                           !(vxflags & VXLAN_F_UDP_CSUM));
+       return 0;
 }
 
 #if IS_ENABLED(CONFIG_IPV6)
@@ -2058,8 +2057,6 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
                        skb = NULL;
                        goto rt_tx_error;
                }
-
-               iptunnel_xmit_stats(err, &dev->stats, dev->tstats);
 #if IS_ENABLED(CONFIG_IPV6)
        } else {
                struct dst_entry *ndst;
@@ -2419,9 +2416,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 = {