diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..65cacdf
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,101 @@
+# FRRouting
+
+FROM ubuntu:16.04
+
+MAINTAINER IWASE Yusuke <iwase.yusuke0@gmail.com>
+ARG user=iwaseyusuke
+ARG branch_name=frr-2.0
+
+USER root
+WORKDIR /root
+
+COPY ENTRYPOINT.sh /ENTRYPOINT.sh
+
+# Install dependencies
+RUN apt-get update && apt-get install -yq --no-install-recommends \
+    git \
+    autoconf \
+    automake \
+    bison \
+    fakeroot \
+    flex \
+    gcc \
+    libc-ares-dev \
+    libjson-c-dev \
+    libpam0g-dev \
+    libsystemd-dev \
+    libpython-dev \
+    libreadline-dev \
+    libtool \
+    make \
+    pkg-config \
+# For editing configurations
+    vim \
+# Utilities
+    iputils-ping \
+    tcpdump \
+    vlan \
+    net-tools \
+    telnet iptables \
+    python python-dev python-distribute python-pip \
+ && pip install pyyaml netaddr scapy futures \
+ && rm -rf /var/lib/apt/lists/* \
+ && mv /bin/ping /sbin/ping \
+ && mv /bin/ping6 /sbin/ping6 \
+ && mv /usr/sbin/tcpdump /usr/bin/tcpdump \
+ && mkdir frr 
+# Copy code to container
+COPY . /frr/
+WORKDIR /frr
+# Build & Install
+RUN  ./bootstrap.sh \
+ && ./configure \
+    --enable-exampledir=/usr/share/doc/frr/examples/ \
+    --localstatedir=/var/run/frr \
+    --sbindir=/usr/lib/frr \
+    --sysconfdir=/etc/frr \
+    --enable-vtysh \
+    --enable-isisd \
+    --enable-pimd \
+    --enable-watchfrr \
+    --enable-ospfclient=yes \
+    --enable-ospfapi=yes \
+    --enable-multipath=64 \
+    --enable-user=root \
+    --enable-group=root \
+    --enable-vty-group=root \
+    --enable-configfile-mask=0640 \
+    --enable-logfile-mask=0640 \
+    --enable-rtadv \
+    --enable-fpm \
+    --enable-ldpd \
+    --enable-systemd \
+    --disable-doc \
+ && make && make install \
+# Re-configure LD_LIBRARY_PATH
+ && echo '/usr/local/lib' > /etc/ld.so.conf.d/usr_local_lib.conf \
+ && ldconfig \
+# Prepare configuration files and directories
+ && mkdir -p /var/log/frr \
+ && mkdir -p /etc/frr \
+ && touch /etc/frr/zebra.conf \
+ && touch /etc/frr/bgpd.conf \
+ && touch /etc/frr/ospfd.conf \
+ && touch /etc/frr/ospf6d.conf \
+ && touch /etc/frr/isisd.conf \
+ && touch /etc/frr/ripd.conf \
+ && touch /etc/frr/ripngd.conf \
+ && touch /etc/frr/pimd.conf \
+ && touch /etc/frr/ldpd.conf \
+ && touch /etc/frr/nhrpd.conf \
+ && touch /etc/frr/vtysh.conf \
+ && cp /frr/tools/etc/frr/debian.conf /etc/frr/debian.conf \
+ && cp /frr/tools/etc/frr/daemons     /etc/frr/daemons \
+# Prepare init.d script
+ && cp /frr/tools/frr /etc/init.d/ \
+ && sed -i "s/frr:frr/root:root/" /etc/init.d/frr \
+# Prepare ENTRYPOINT.sh
+# && chmod +x /ENTRYPOINT.sh
+
+#ENTRYPOINT ["/ENTRYPOINT.sh"]
+
diff --git a/ENTRYPOINT.sh b/ENTRYPOINT.sh
new file mode 100644
index 0000000..4002322
--- /dev/null
+++ b/ENTRYPOINT.sh
@@ -0,0 +1,18 @@
+#!/usr/bin/env bash
+
+for DAEMON in $FRR_DAEMONS
+do
+    if [ -s "/usr/lib/frr/${DAEMON}" ]
+    then
+        touch /etc/frr/${DAEMON}.conf
+        sed -i "s/${DAEMON}=no/${DAEMON}=yes/" /etc/frr/daemons
+    else
+        echo "No such daemon: ${DAEMON}"
+    fi
+done
+
+service frr restart > /dev/null 2>&1
+
+bash
+
+service frr stop > /dev/null 2>&1
diff --git a/tools/etc/frr/daemons b/tools/etc/frr/daemons
index 9a96c04..c93e8db 100644
--- a/tools/etc/frr/daemons
+++ b/tools/etc/frr/daemons
@@ -21,8 +21,8 @@
 # The watchfrr daemon is always started. Per default in monitoring-only but
 # that can be changed via /etc/frr/daemons.conf.
 #
-zebra=no
-bgpd=no
+zebra=yes
+bgpd=yes
 ospfd=no
 ospf6d=no
 ripd=no
diff --git a/zebra/router-id.h b/zebra/router-id.h
index 6b15159..4590b57 100644
--- a/zebra/router-id.h
+++ b/zebra/router-id.h
@@ -36,5 +36,6 @@ extern void router_id_init(struct zebra_vrf *);
 extern void router_id_cmd_init(void);
 extern void router_id_write(struct vty *);
 extern void router_id_get(struct prefix *, vrf_id_t);
+//extern int fpm_remote_srv_write (struct vty *vty );
 
 #endif
diff --git a/zebra/zebra_fpm.c b/zebra/zebra_fpm.c
index 9d3133f..1392193 100644
--- a/zebra/zebra_fpm.c
+++ b/zebra/zebra_fpm.c
@@ -23,6 +23,7 @@
 
 #include <zebra.h>
 
+#include "zebra_fpm.h"
 #include "log.h"
 #include "libfrr.h"
 #include "stream.h"
@@ -1537,10 +1538,15 @@ static inline void zfpm_init_message_format(const char *format)
 	zlog_warn("Unknown fpm format '%s'", format);
 }
 
+
+/* Zebra node  */
+static struct cmd_node zebra_node = {ZEBRA_NODE, "", 1};
+
+
 /**
- * fpm_remote_srv_write
+ * fpm_remote_srv_write 
  *
- * Module to write remote fpm connection
+ * Module to write remote fpm connection 
  *
  * Returns ZERO on success.
  */
@@ -1560,11 +1566,6 @@ static int fpm_remote_srv_write(struct vty *vty)
 	return 0;
 }
 
-
-/* Zebra node  */
-static struct cmd_node zebra_node = {ZEBRA_NODE, "", 1};
-
-
 /**
  * zfpm_init
  *
@@ -1592,7 +1593,7 @@ static int zfpm_init(struct thread_master *master)
 	zfpm_stats_init(&zfpm_g->last_ivl_stats);
 	zfpm_stats_init(&zfpm_g->cumulative_stats);
 
-	install_node(&zebra_node, fpm_remote_srv_write);
+        install_node(&zebra_node, fpm_remote_srv_write);
 	install_element(ENABLE_NODE, &show_zebra_fpm_stats_cmd);
 	install_element(ENABLE_NODE, &clear_zebra_fpm_stats_cmd);
 	install_element(CONFIG_NODE, &fpm_remote_ip_cmd);
diff --git a/zebra/zebra_fpm.h b/zebra/zebra_fpm.h
new file mode 100644
index 0000000..9291ffa
--- /dev/null
+++ b/zebra/zebra_fpm.h
@@ -0,0 +1,35 @@
+/*
+ * Router ID for zebra daemon.
+ *
+ * Copyright (C) 2004 James R. Leu
+ *
+ * This file is part of Quagga routing suite.
+ *
+ * Quagga is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2, or (at your option) any
+ * later version.
+ *
+ * Quagga is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; see the file COPYING; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef _ZEBRA_VTY_H_
+#define _ZEBRA_VTY_H_
+
+#include <zebra.h>
+#include "memory.h"
+#include "prefix.h"
+#include "zclient.h"
+#include "if.h"
+
+
+static int fpm_remote_srv_write (struct vty *vty );
+
+#endif
diff --git a/zebra/zebra_fpm_netlink.c b/zebra/zebra_fpm_netlink.c
index c27884e..38ead15 100644
--- a/zebra/zebra_fpm_netlink.c
+++ b/zebra/zebra_fpm_netlink.c
@@ -454,4 +454,121 @@ int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest, struct route_entry *re,
 	return netlink_route_info_encode(ri, in_buf, in_buf_len);
 }
 
+/*
+ * zfpm_netlink_receive_message
+ *
+ * Process add/delete route netlink messages.
+ */
+int
+zfpm_netlink_receive_message (struct  nlmsghdr *nlh)
+{
+  struct  prefix p;
+  struct  rtmsg *route_entry;
+  struct  rtattr *route_attribute;
+  int     route_attribute_len = 0;
+  int     received_bytes = nlh->nlmsg_len;
+  struct  in_addr gate_addr;
+  struct  in6_addr gate_addr6;
+  u_char  flag = 0;
+  u_char distance = ZEBRA_STATIC_DISTANCE_DEFAULT;
+
+  zlog_debug ("NLM msg rx len=%d type=%d", received_bytes, nlh->nlmsg_type);
+
+  /* Only add/delete route supported. */
+  if (!(nlh->nlmsg_type == RTM_NEWROUTE ||
+        nlh->nlmsg_type == RTM_DELROUTE)) {
+      zlog_warn ("nlmsg_type=%d not supported\n", nlh->nlmsg_type);
+      return 0;
+  }
+
+  /* Get the route data. */
+  route_entry = (struct rtmsg *) NLMSG_DATA(nlh);
+
+  /* Get attributes of route_entry. */
+  route_attribute = (struct rtattr *) RTM_RTA(route_entry);
+
+  /* Get the route atttibutes len. */
+  route_attribute_len = RTM_PAYLOAD(nlh);
+
+  /* IPv4 */
+  if (route_entry->rtm_family == AF_INET) {
+
+    /* Loop through all attributes. */
+    for ( ; RTA_OK(route_attribute, route_attribute_len);
+      route_attribute = RTA_NEXT(route_attribute, route_attribute_len)) {
+
+      /* Get the prefix. */
+      if (route_attribute->rta_type == RTA_DST) {
+        memcpy(&(p.u.prefix), RTA_DATA(route_attribute), af_addr_size(AF_INET));
+        p.family = AF_INET;
+        p.prefixlen = route_entry->rtm_dst_len;
+      }
+
+      /* Get the gateway/next hop. */
+      if (route_attribute->rta_type == RTA_GATEWAY) {
+        memcpy(&gate_addr, RTA_DATA(route_attribute), af_addr_size(AF_INET));
+      }
+    }
+
+    if (nlh->nlmsg_type == RTM_NEWROUTE) {
+
+      /* Add the static route. */
+      static_add_ipv4 (&p, &gate_addr, NULL, flag, distance, 0);
+
+      zlog_debug("IPv4 add route=%s/%d", prefix_addr_to_a(&p), p.prefixlen);
+      zlog_debug("     gateway=%s", addr_to_a(AF_INET, &gate_addr));
+    }
+    else {
+
+      /* Delete the static route. */
+      static_delete_ipv4 (&p, &gate_addr, NULL, distance, 0);
+
+      zlog_debug("IPv4 delete route=%s/%d", prefix_addr_to_a(&p), p.prefixlen);
+      zlog_debug("     gateway=%s", addr_to_a(AF_INET, &gate_addr));
+    }
+  }
+
+#ifdef HAVE_IPV6
+  /* IPv6 */
+  else {
+    /* Loop through all attributes. */
+    for ( ; RTA_OK(route_attribute, route_attribute_len);
+      route_attribute = RTA_NEXT(route_attribute, route_attribute_len)) {
+
+      /* Get the prefix. */
+      if (route_attribute->rta_type == RTA_DST) {
+        memcpy(&(p.u.prefix), RTA_DATA(route_attribute), af_addr_size(AF_INET6));
+        p.family = AF_INET6;
+        p.prefixlen = route_entry->rtm_dst_len;
+      }
+
+      /* Get the gateway/next hop. */
+      if (route_attribute->rta_type == RTA_GATEWAY) {
+        memcpy(&gate_addr6, RTA_DATA(route_attribute), af_addr_size(AF_INET6));
+      }
+    }
+
+    if (nlh->nlmsg_type == RTM_NEWROUTE) {
+
+      /* Add the static route. */
+      static_add_ipv6 (&p, STATIC_IPV6_GATEWAY,
+        &gate_addr6, NULL, flag, distance, 0);
+
+      zlog_debug("IPv6 add route=%s/%d", prefix_addr_to_a(&p), p.prefixlen);
+      zlog_debug("     gateway=%s", addr_to_a(AF_INET6, &gate_addr6));
+    }
+    else {
+
+      /* Delete the static route. */
+      static_delete_ipv6 (&p, STATIC_IPV6_GATEWAY,
+        &gate_addr6, NULL, distance, 0);
+
+      zlog_debug("IPv6 delete route=%s/%d", prefix_addr_to_a(&p), p.prefixlen);
+      zlog_debug("     gateway=%s", addr_to_a(AF_INET6, &gate_addr6));
+    }
+  }
+#endif /* HAVE_IPV6 */
+
+return 1;
+}
 #endif /* HAVE_NETLINK */
diff --git a/zebra/zebra_fpm_private.h b/zebra/zebra_fpm_private.h
index 969ab6c..1f6e52c 100644
--- a/zebra/zebra_fpm_private.h
+++ b/zebra/zebra_fpm_private.h
@@ -60,5 +60,7 @@ extern int zfpm_netlink_encode_route(int cmd, rib_dest_t *dest,
 extern int zfpm_protobuf_encode_route(rib_dest_t *dest, struct route_entry *re,
 				      uint8_t *in_buf, size_t in_buf_len);
 
+extern int zfpm_netlink_receive_message (struct nlmsghdr *nlh);
+
 extern struct route_entry *zfpm_route_for_update(rib_dest_t *dest);
 #endif /* _ZEBRA_FPM_PRIVATE_H */
diff --git a/zebra/zebra_vty.c b/zebra/zebra_vty.c
index 43d76a6..03c4a6b 100644
--- a/zebra/zebra_vty.c
+++ b/zebra/zebra_vty.c
@@ -20,6 +20,7 @@
 
 #include <zebra.h>
 
+#include "zebra_fpm.h"
 #include "memory.h"
 #include "zebra_memory.h"
 #include "if.h"
@@ -54,6 +55,7 @@
 #include "zebra/zebra_pbr.h"
 
 extern int allow_delete;
+//extern int fpm_remote_srv_write (struct vty *vty );
 
 static int do_show_ip_route(struct vty *vty, const char *vrf_name, afi_t afi,
 			    safi_t safi, bool use_fib, uint8_t use_json,
@@ -3687,12 +3689,32 @@ static struct cmd_node forwarding_node = {FORWARDING_NODE,
 					  "", /* This node has no interface. */
 					  1};
 
+//#ifdef HAVE_FPM
+
+/* function to write the fpm config info */
+static int config_write_fpm (struct vty *vty)
+{
+  return fpm_remote_srv_write (vty);
+}
+
+/* Zebra node  */
+static struct cmd_node zebra_node =
+{
+  ZEBRA_NODE,
+  "",
+  1
+};
+//#endif
+
 /* Route VTY.  */
 void zebra_vty_init(void)
 {
 	/* Install configuration write function. */
 	install_node(&table_node, config_write_table);
 	install_node(&forwarding_node, config_write_forwarding);
+//#ifdef HAVE_FPM
+    install_node (&zebra_node, config_write_fpm);
+//#endif
 
 	install_element(VIEW_NODE, &show_ip_forwarding_cmd);
 	install_element(CONFIG_NODE, &ip_forwarding_cmd);
diff --git a/zebra/zserv.h b/zebra/zserv.h
index a5b5acb..5551f30 100644
--- a/zebra/zserv.h
+++ b/zebra/zserv.h
@@ -175,7 +175,7 @@ extern unsigned int multipath_num;
 extern void zserv_init(void);
 extern void zebra_zserv_socket_init(char *path);
 extern int zebra_server_send_message(struct zserv *client, struct stream *msg);
-
+//extern int fpm_remote_srv_write (struct vty *vty );
 extern struct zserv *zebra_find_client(uint8_t proto, unsigned short instance);
 
 #if defined(HANDLE_ZAPI_FUZZING)
