--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -90,6 +90,20 @@ struct vxlan_fdb {
 /* salt for hash table */
 static u32 vxlan_salt __read_mostly;
 
+ATOMIC_NOTIFIER_HEAD(vxlan_fdb_notifier_list);
+
+void vxlan_fdb_register_notify(struct notifier_block *nb)
+{
+	atomic_notifier_chain_register(&vxlan_fdb_notifier_list, nb);
+}
+EXPORT_SYMBOL(vxlan_fdb_register_notify);
+
+void vxlan_fdb_unregister_notify(struct notifier_block *nb)
+{
+	atomic_notifier_chain_unregister(&vxlan_fdb_notifier_list, nb);
+}
+EXPORT_SYMBOL(vxlan_fdb_unregister_notify);
+
 static inline bool vxlan_collect_metadata(struct vxlan_sock *vs)
 {
 	return vs->flags & VXLAN_F_COLLECT_METADATA ||
@@ -367,6 +381,7 @@ static void __vxlan_fdb_notify(struct vx
 {
 	struct net *net = dev_net(vxlan->dev);
 	struct sk_buff *skb;
+	struct vxlan_fdb_event vfe;
 	int err = -ENOBUFS;
 
 	skb = nlmsg_new(vxlan_nlmsg_size(), GFP_ATOMIC);
@@ -382,6 +397,10 @@ static void __vxlan_fdb_notify(struct vx
 	}
 
 	rtnl_notify(skb, net, 0, RTNLGRP_NEIGH, NULL, GFP_ATOMIC);
+	vfe.dev = vxlan->dev;
+	vfe.rdst = rd;
+	ether_addr_copy(vfe.eth_addr, fdb->eth_addr);
+	atomic_notifier_call_chain(&vxlan_fdb_notifier_list, type, (void *)&vfe);
 	return;
 errout:
 	if (err < 0)
@@ -548,6 +567,18 @@ static struct vxlan_fdb *vxlan_find_mac(
 	return f;
 }
 
+/* Find and update age of fdb entry corresponding to MAC. */
+void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni)
+{
+	u32 hash_index;
+
+	hash_index = fdb_head_index(vxlan, mac, vni);
+	spin_lock_bh(&vxlan->hash_lock[hash_index]);
+	vxlan_find_mac(vxlan, mac, vni);
+	spin_unlock_bh(&vxlan->hash_lock[hash_index]);
+}
+EXPORT_SYMBOL(vxlan_fdb_update_mac);
+
 /* caller should hold vxlan->hash_lock */
 static struct vxlan_rdst *vxlan_fdb_find_rdst(struct vxlan_fdb *f,
 					      union vxlan_addr *ip, __be16 port,
@@ -2746,6 +2777,9 @@ static void vxlan_xmit_one(struct sk_buf
 			goto out_unlock;
 		}
 
+		/* Reset the skb_iif to Tunnels interface index */
+		skb->skb_iif = dev->ifindex;
+
 		tos = ip_tunnel_ecn_encap(tos, old_iph, skb);
 		ttl = ttl ? : ip4_dst_hoplimit(&rt->dst);
 		err = vxlan_build_skb(skb, ndst, sizeof(struct iphdr),
@@ -2817,6 +2851,9 @@ static void vxlan_xmit_one(struct sk_buf
 		if (err < 0)
 			goto tx_error;
 
+		/* Reset the skb_iif to Tunnels interface index */
+		skb->skb_iif = dev->ifindex;
+
 		udp_tunnel6_xmit_skb(ndst, sock6->sock->sk, skb, dev,
 				     &local_ip.sin6.sin6_addr,
 				     &dst->sin6.sin6_addr, tos, ttl,
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -293,6 +293,19 @@ struct vxlan_dev {
 					 VXLAN_F_UDP_ZERO_CSUM6_RX |	\
 					 VXLAN_F_COLLECT_METADATA)
 
+/*
+ * Application data for fdb notifier event
+ */
+struct vxlan_fdb_event {
+	struct net_device *dev;
+	struct vxlan_rdst *rdst;
+	u8 eth_addr[ETH_ALEN];
+};
+
+extern void vxlan_fdb_register_notify(struct notifier_block *nb);
+extern void vxlan_fdb_unregister_notify(struct notifier_block *nb);
+extern void vxlan_fdb_update_mac(struct vxlan_dev *vxlan, const u8 *mac, uint32_t vni);
+
 struct net_device *vxlan_dev_create(struct net *net, const char *name,
 				    u8 name_assign_type, struct vxlan_config *conf);
 
@@ -381,6 +394,15 @@ static inline __be32 vxlan_compute_rco(u
 	return vni_field;
 }
 
+/*
+ * vxlan_get_vni()
+ *	Returns the vni corresponding to tunnel
+ */
+static inline u32 vxlan_get_vni(struct vxlan_dev *vxlan_tun)
+{
+	return be32_to_cpu(vxlan_tun->cfg.vni);
+}
+
 static inline unsigned short vxlan_get_sk_family(struct vxlan_sock *vs)
 {
 	return vs->sock->sk->sk_family;
