aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/vxlan.c31
1 files changed, 20 insertions, 11 deletions
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 8be9bf07bd39..92150c0cf4d9 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -621,6 +621,22 @@ static inline u8 vxlan_ecn_encap(u8 tos,
621 return INET_ECN_encapsulate(tos, inner); 621 return INET_ECN_encapsulate(tos, inner);
622} 622}
623 623
624static __be32 vxlan_find_dst(struct vxlan_dev *vxlan, struct sk_buff *skb)
625{
626 const struct ethhdr *eth = (struct ethhdr *) skb->data;
627 const struct vxlan_fdb *f;
628
629 if (is_multicast_ether_addr(eth->h_dest))
630 return vxlan->gaddr;
631
632 f = vxlan_find_mac(vxlan, eth->h_dest);
633 if (f)
634 return f->remote_ip;
635 else
636 return vxlan->gaddr;
637
638}
639
624/* Transmit local packets over Vxlan 640/* Transmit local packets over Vxlan
625 * 641 *
626 * Outer IP header inherits ECN and DF from inner header. 642 * Outer IP header inherits ECN and DF from inner header.
@@ -632,13 +648,11 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
632{ 648{
633 struct vxlan_dev *vxlan = netdev_priv(dev); 649 struct vxlan_dev *vxlan = netdev_priv(dev);
634 struct rtable *rt; 650 struct rtable *rt;
635 const struct ethhdr *eth;
636 const struct iphdr *old_iph; 651 const struct iphdr *old_iph;
637 struct iphdr *iph; 652 struct iphdr *iph;
638 struct vxlanhdr *vxh; 653 struct vxlanhdr *vxh;
639 struct udphdr *uh; 654 struct udphdr *uh;
640 struct flowi4 fl4; 655 struct flowi4 fl4;
641 struct vxlan_fdb *f;
642 unsigned int pkt_len = skb->len; 656 unsigned int pkt_len = skb->len;
643 u32 hash; 657 u32 hash;
644 __be32 dst; 658 __be32 dst;
@@ -646,21 +660,16 @@ static netdev_tx_t vxlan_xmit(struct sk_buff *skb, struct net_device *dev)
646 __u8 tos, ttl; 660 __u8 tos, ttl;
647 int err; 661 int err;
648 662
663 dst = vxlan_find_dst(vxlan, skb);
664 if (!dst)
665 goto drop;
666
649 /* Need space for new headers (invalidates iph ptr) */ 667 /* Need space for new headers (invalidates iph ptr) */
650 if (skb_cow_head(skb, VXLAN_HEADROOM)) 668 if (skb_cow_head(skb, VXLAN_HEADROOM))
651 goto drop; 669 goto drop;
652 670
653 eth = (void *)skb->data;
654 old_iph = ip_hdr(skb); 671 old_iph = ip_hdr(skb);
655 672
656 if (!is_multicast_ether_addr(eth->h_dest) &&
657 (f = vxlan_find_mac(vxlan, eth->h_dest)))
658 dst = f->remote_ip;
659 else if (vxlan->gaddr) {
660 dst = vxlan->gaddr;
661 } else
662 goto drop;
663
664 ttl = vxlan->ttl; 673 ttl = vxlan->ttl;
665 if (!ttl && IN_MULTICAST(ntohl(dst))) 674 if (!ttl && IN_MULTICAST(ntohl(dst)))
666 ttl = 1; 675 ttl = 1;