diff --git a/mcproxy/include/parser/configuration.hpp b/mcproxy/include/parser/configuration.hpp
index 801b7fbb45660ff1723a1a1cca81c5402667c98f..5141ca5d954968e43852d585399c36b5f0ca0e82 100644
--- a/mcproxy/include/parser/configuration.hpp
+++ b/mcproxy/include/parser/configuration.hpp
@@ -45,7 +45,7 @@ private:
     int m_qri = -1; // Query response interval
     int m_lmqi = -1; // Last member Query interval
     int m_rv = -1; // robustness value
-    bool m_fastleave = true; // Fast leave
+    bool m_fastleave = false; // Fast leave
 
     //<line number (for a better error message output), command>
     std::vector<std::pair<unsigned int, std::string>> m_cmds;
diff --git a/mcproxy/include/proxy/timers_values.hpp b/mcproxy/include/proxy/timers_values.hpp
index 03ba3136f44a32c099d20c31c36318e884180433..808c348f4c532706768ffaa90964d3f158a4afab 100644
--- a/mcproxy/include/proxy/timers_values.hpp
+++ b/mcproxy/include/proxy/timers_values.hpp
@@ -36,6 +36,7 @@ struct timers_values_tank {
     std::chrono::milliseconds last_listener_query_interval = std::chrono::milliseconds(1000);
     unsigned int last_listener_query_count = robustness_variable;
     std::chrono::milliseconds unsolicited_report_interval = std::chrono::milliseconds(1000);
+    bool fastleave = false;
 };
 
 static timers_values_tank default_timers_values_tank = timers_values_tank();
@@ -82,6 +83,7 @@ public:
     std::chrono::milliseconds get_last_listener_query_time() const; //
     std::chrono::milliseconds get_unsolicited_report_interval() const;
     std::chrono::milliseconds get_older_host_present_interval() const; //
+    bool get_fastleave() const;
 
     void set_robustness_variable(unsigned int robustness_variable);
     void set_query_interval(std::chrono::seconds query_interval);
@@ -91,6 +93,7 @@ public:
     void set_last_listener_query_interval(std::chrono::milliseconds last_listener_query_interval);
     void set_last_listener_query_count(unsigned int last_listener_query_count);
     void set_unsolicited_report_interval(std::chrono::milliseconds unsolicited_report_interval);
+    void set_fastleave(bool fastleave);
 
     void reset_to_default_tank();
 
diff --git a/mcproxy/src/proxy/proxy.cpp b/mcproxy/src/proxy/proxy.cpp
index 34b3ee9af85183319f01b3954191d8a17114071f..7f1a446131239e102dbdff2f6645003d103a31c7 100644
--- a/mcproxy/src/proxy/proxy.cpp
+++ b/mcproxy/src/proxy/proxy.cpp
@@ -276,7 +276,9 @@ void proxy::start_proxy_instances()
                     tv.set_startup_query_count(val);
             }
 
-            std::cout << "fastleave :" <<m_configuration->get_fastleave() <<std::endl;
+            bool fastleave = m_configuration->get_fastleave();
+            std::cout << "fastleave :" <<fastleave <<std::endl;
+            tv.set_fastleave(fastleave);
 
             pr_i->add_msg(std::make_shared<config_msg>(config_msg::ADD_DOWNSTREAM, if_index, d, tv));
         }
diff --git a/mcproxy/src/proxy/querier.cpp b/mcproxy/src/proxy/querier.cpp
index 9e6c32297f7844b62160614822b843e29da9d6a7..c4f8b9e8ab051358bb227b0c109c79b9d516b71f 100644
--- a/mcproxy/src/proxy/querier.cpp
+++ b/mcproxy/src/proxy/querier.cpp
@@ -35,6 +35,95 @@
 #include <iostream>
 #include <sstream>
 
+extern "C" {
+
+#include <netinet/ip.h>
+#include <linux/if_bridge.h>
+#include <asm/types.h>
+#include <libnetlink.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+
+#ifndef MDBA_RTA
+#define MDBA_RTA(r) \
+        ((struct rtattr*)(((char*)(r)) + NLMSG_ALIGN(sizeof(struct br_port_msg))))
+#endif
+
+static unsigned int group_ports = 0;
+
+static void
+check_mdb_entry(struct nlmsghdr *n, struct in_addr *gaddr, struct rtattr *attr)
+{
+    struct rtattr *i;
+    struct br_mdb_entry *e;
+
+    int rem = RTA_PAYLOAD(attr);
+    for (i = (struct rtattr *) RTA_DATA(attr); RTA_OK(i, rem); i = RTA_NEXT(i, rem)) {
+        e = (br_mdb_entry*) RTA_DATA(i);
+
+        if (e->addr.proto == htons(ETH_P_IP) && e->addr.u.ip4 == gaddr->s_addr)
+            group_ports++;
+    }
+}
+
+static int parse_mdb(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+{
+    struct in_addr *gaddr = (struct in_addr *) arg;
+    struct br_port_msg *r = (struct br_port_msg *) NLMSG_DATA(n);
+    int len = n->nlmsg_len;
+    struct rtattr *tb[MDBA_MAX + 1];
+
+    if (n->nlmsg_type != RTM_GETMDB)
+        return -1;
+
+    len -= NLMSG_LENGTH(sizeof (*r));
+    if (len < 0) {
+        printf("BUG: wrong nlmsg len %d\n", len);
+        return -1;
+    }
+
+    parse_rtattr(tb, MDBA_MAX, MDBA_RTA(r), n->nlmsg_len - NLMSG_LENGTH(sizeof (*r)));
+
+    if (tb[MDBA_MDB]) {
+        struct rtattr *i;
+        int rem = RTA_PAYLOAD(tb[MDBA_MDB]);
+
+        for (i = (struct rtattr*) RTA_DATA(tb[MDBA_MDB]); RTA_OK(i, rem); i = RTA_NEXT(i, rem))
+            check_mdb_entry(n, gaddr, i);
+    }
+
+    return 0;
+}
+
+unsigned int group_mem_port_count(struct in_addr gaddr)
+{
+    struct rtnl_handle rth;
+
+    group_ports = 0;
+
+    if (rtnl_open(&rth, 0) < 0) {
+        printf("rtnl_open() failed\n");
+        goto out;
+    }
+
+    if (rtnl_wilddump_request(&rth, PF_BRIDGE, RTM_GETMDB) < 0) {
+        printf("Cannot send RTM_GETMDG dump request\n");
+        goto out;
+    }
+
+    if (rtnl_dump_filter(&rth, parse_mdb, &gaddr) < 0) {
+        printf("Dump terminated\n");
+        goto out;
+    }
+
+out:
+    rtnl_close(&rth);
+
+    return group_ports;
+}
+
+}
+
 querier::querier(worker* msg_worker, group_mem_protocol querier_version_mode, int if_index, const std::shared_ptr<const sender>& sender, const std::shared_ptr<timing>& timing, const timers_values& tv, callback_querier_state_change cb_state_change)
     : m_msg_worker(msg_worker)
     , m_if_index(if_index)
@@ -163,7 +252,15 @@ void querier::receive_record(const std::shared_ptr<proxy_msg>& msg)
 
         break;
     case EXCLUDE_MODE:
-        receive_record_in_exclude_mode(gr->get_record_type(), gr->get_gaddr(), gr->get_slist(), db_info_it->second);
+        if (m_timers_values.get_fastleave() && gr->get_record_type() == CHANGE_TO_INCLUDE_MODE && gr->get_slist().empty()) {
+            //Only leave the group on upstream, when no any LAN port in the group
+            if (!group_mem_port_count(gr->get_gaddr().get_in_addr())) {
+                m_db.group_info.erase(db_info_it);
+                state_change_notification(gr->get_gaddr());
+            }
+        } else
+            receive_record_in_exclude_mode(gr->get_record_type(), gr->get_gaddr(), gr->get_slist(), db_info_it->second);
+
         break;
     default :
         HC_LOG_ERROR("wrong filter mode: " << db_info_it->second.filter_mode);
@@ -778,6 +875,7 @@ void querier::state_change_notification(const addr_storage& gaddr)
     m_cb_state_change(m_if_index, gaddr);
 }
 
+
 querier::~querier()
 {
     HC_LOG_TRACE("");
diff --git a/mcproxy/src/proxy/timers_values.cpp b/mcproxy/src/proxy/timers_values.cpp
index 164e47a0e98da594e53cf3ef7a15b6c0d61d452f..67959d15ae4ee9f9b931e722c0a2f6c2fcfc61b3 100644
--- a/mcproxy/src/proxy/timers_values.cpp
+++ b/mcproxy/src/proxy/timers_values.cpp
@@ -176,6 +176,12 @@ uint16_t timers_values::maxrespi_to_maxrespc_mldv2(const std::chrono::millisecon
 }
 
 //--------------------------------------
+bool timers_values::get_fastleave() const
+{
+    HC_LOG_TRACE("");
+    return tank->fastleave;
+}
+
 unsigned int timers_values::get_robustness_variable() const
 {
     HC_LOG_TRACE("");
@@ -271,6 +277,13 @@ void timers_values::reset_to_default_tank()
 }
 
 //--------------------------------------
+void timers_values::set_fastleave(bool fastleave)
+{
+    HC_LOG_TRACE("");
+    set_new_tank();
+    tank->fastleave = fastleave;
+}
+
 void timers_values::set_robustness_variable(unsigned int robustness_variable)
 {
     HC_LOG_TRACE("");