backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / bgp / bgpspeaker.py
diff --git a/ryu/build/lib.linux-armv7l-2.7/ryu/services/protocols/bgp/bgpspeaker.py b/ryu/build/lib.linux-armv7l-2.7/ryu/services/protocols/bgp/bgpspeaker.py
new file mode 100644 (file)
index 0000000..2f53f63
--- /dev/null
@@ -0,0 +1,1392 @@
+# Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#    http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+"""This module offers a class to enable your code to speak BGP protocol.
+
+"""
+
+import netaddr
+from ryu.lib import hub
+from ryu.lib import ip
+from ryu.lib.packet.bgp import (
+    BGPFlowSpecTrafficActionCommunity,
+    BGPFlowSpecVlanActionCommunity,
+    BGPFlowSpecTPIDActionCommunity,
+)
+
+from ryu.services.protocols.bgp.core_manager import CORE_MANAGER
+from ryu.services.protocols.bgp.signals.emit import BgpSignalBus
+from ryu.services.protocols.bgp.api.base import call
+from ryu.services.protocols.bgp.api.base import PREFIX
+from ryu.services.protocols.bgp.api.base import EVPN_ROUTE_TYPE
+from ryu.services.protocols.bgp.api.base import EVPN_ESI
+from ryu.services.protocols.bgp.api.base import EVPN_ETHERNET_TAG_ID
+from ryu.services.protocols.bgp.api.base import REDUNDANCY_MODE
+from ryu.services.protocols.bgp.api.base import IP_ADDR
+from ryu.services.protocols.bgp.api.base import MAC_ADDR
+from ryu.services.protocols.bgp.api.base import NEXT_HOP
+from ryu.services.protocols.bgp.api.base import IP_PREFIX
+from ryu.services.protocols.bgp.api.base import GW_IP_ADDR
+from ryu.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER
+from ryu.services.protocols.bgp.api.base import ROUTE_FAMILY
+from ryu.services.protocols.bgp.api.base import EVPN_VNI
+from ryu.services.protocols.bgp.api.base import TUNNEL_TYPE
+from ryu.services.protocols.bgp.api.base import PMSI_TUNNEL_TYPE
+from ryu.services.protocols.bgp.api.prefix import EVPN_MAX_ET
+from ryu.services.protocols.bgp.api.prefix import ESI_TYPE_LACP
+from ryu.services.protocols.bgp.api.prefix import ESI_TYPE_L2_BRIDGE
+from ryu.services.protocols.bgp.api.prefix import ESI_TYPE_MAC_BASED
+from ryu.services.protocols.bgp.api.prefix import EVPN_ETH_AUTO_DISCOVERY
+from ryu.services.protocols.bgp.api.prefix import EVPN_MAC_IP_ADV_ROUTE
+from ryu.services.protocols.bgp.api.prefix import EVPN_MULTICAST_ETAG_ROUTE
+from ryu.services.protocols.bgp.api.prefix import EVPN_ETH_SEGMENT
+from ryu.services.protocols.bgp.api.prefix import EVPN_IP_PREFIX_ROUTE
+from ryu.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_ALL_ACTIVE
+from ryu.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_SINGLE_ACTIVE
+from ryu.services.protocols.bgp.api.prefix import TUNNEL_TYPE_VXLAN
+from ryu.services.protocols.bgp.api.prefix import TUNNEL_TYPE_NVGRE
+from ryu.services.protocols.bgp.api.prefix import (
+    PMSI_TYPE_NO_TUNNEL_INFO,
+    PMSI_TYPE_INGRESS_REP)
+from ryu.services.protocols.bgp.api.prefix import (
+    FLOWSPEC_FAMILY,
+    FLOWSPEC_FAMILY_IPV4,
+    FLOWSPEC_FAMILY_VPNV4,
+    FLOWSPEC_FAMILY_IPV6,
+    FLOWSPEC_FAMILY_VPNV6,
+    FLOWSPEC_FAMILY_L2VPN,
+    FLOWSPEC_RULES,
+    FLOWSPEC_ACTIONS)
+from ryu.services.protocols.bgp.model import ReceivedRoute
+from ryu.services.protocols.bgp.rtconf.common import LOCAL_AS
+from ryu.services.protocols.bgp.rtconf.common import ROUTER_ID
+from ryu.services.protocols.bgp.rtconf.common import CLUSTER_ID
+from ryu.services.protocols.bgp.rtconf.common import BGP_SERVER_HOSTS
+from ryu.services.protocols.bgp.rtconf.common import BGP_SERVER_PORT
+from ryu.services.protocols.bgp.rtconf.common import DEFAULT_BGP_SERVER_HOSTS
+from ryu.services.protocols.bgp.rtconf.common import DEFAULT_BGP_SERVER_PORT
+from ryu.services.protocols.bgp.rtconf.common import (
+    DEFAULT_REFRESH_MAX_EOR_TIME, DEFAULT_REFRESH_STALEPATH_TIME)
+from ryu.services.protocols.bgp.rtconf.common import DEFAULT_LABEL_RANGE
+from ryu.services.protocols.bgp.rtconf.common import REFRESH_MAX_EOR_TIME
+from ryu.services.protocols.bgp.rtconf.common import REFRESH_STALEPATH_TIME
+from ryu.services.protocols.bgp.rtconf.common import LABEL_RANGE
+from ryu.services.protocols.bgp.rtconf.common import ALLOW_LOCAL_AS_IN_COUNT
+from ryu.services.protocols.bgp.rtconf.common import LOCAL_PREF
+from ryu.services.protocols.bgp.rtconf.common import DEFAULT_LOCAL_PREF
+from ryu.services.protocols.bgp.rtconf import neighbors
+from ryu.services.protocols.bgp.rtconf import vrfs
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_EVPN
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6FS
+from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_L2VPNFS
+from ryu.services.protocols.bgp.rtconf.base import CAP_ENHANCED_REFRESH
+from ryu.services.protocols.bgp.rtconf.base import CAP_FOUR_OCTET_AS_NUMBER
+from ryu.services.protocols.bgp.rtconf.base import MULTI_EXIT_DISC
+from ryu.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS
+from ryu.services.protocols.bgp.rtconf.neighbors import (
+    DEFAULT_CAP_MBGP_IPV4,
+    DEFAULT_CAP_MBGP_IPV6,
+    DEFAULT_CAP_MBGP_VPNV4,
+    DEFAULT_CAP_MBGP_VPNV6,
+    DEFAULT_CAP_MBGP_EVPN,
+    DEFAULT_CAP_MBGP_IPV4FS,
+    DEFAULT_CAP_MBGP_IPV6FS,
+    DEFAULT_CAP_MBGP_VPNV4FS,
+    DEFAULT_CAP_MBGP_VPNV6FS,
+    DEFAULT_CAP_MBGP_L2VPNFS,
+    DEFAULT_CAP_ENHANCED_REFRESH,
+    DEFAULT_CAP_FOUR_OCTET_AS_NUMBER,
+    DEFAULT_CONNECT_MODE,
+    REMOTE_PORT,
+    DEFAULT_BGP_PORT,
+    PEER_NEXT_HOP,
+    PASSWORD,
+    DEFAULT_IS_ROUTE_SERVER_CLIENT,
+    IS_ROUTE_SERVER_CLIENT,
+    DEFAULT_IS_ROUTE_REFLECTOR_CLIENT,
+    IS_ROUTE_REFLECTOR_CLIENT,
+    DEFAULT_IS_NEXT_HOP_SELF,
+    IS_NEXT_HOP_SELF,
+    CONNECT_MODE,
+    LOCAL_ADDRESS,
+    LOCAL_PORT,
+)
+from ryu.services.protocols.bgp.rtconf.vrfs import SUPPORTED_VRF_RF
+from ryu.services.protocols.bgp.info_base.base import Filter
+from ryu.services.protocols.bgp.info_base.ipv4 import Ipv4Path
+from ryu.services.protocols.bgp.info_base.ipv6 import Ipv6Path
+from ryu.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path
+from ryu.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path
+from ryu.services.protocols.bgp.info_base.evpn import EvpnPath
+
+
+NEIGHBOR_CONF_MED = MULTI_EXIT_DISC  # for backward compatibility
+RF_VPN_V4 = vrfs.VRF_RF_IPV4
+RF_VPN_V6 = vrfs.VRF_RF_IPV6
+RF_L2_EVPN = vrfs.VRF_RF_L2_EVPN
+RF_VPNV4_FLOWSPEC = vrfs.VRF_RF_IPV4_FLOWSPEC
+RF_VPNV6_FLOWSPEC = vrfs.VRF_RF_IPV6_FLOWSPEC
+RF_L2VPN_FLOWSPEC = vrfs.VRF_RF_L2VPN_FLOWSPEC
+
+# Constants for the Traffic Filtering Actions of Flow Specification.
+FLOWSPEC_TA_SAMPLE = BGPFlowSpecTrafficActionCommunity.SAMPLE
+FLOWSPEC_TA_TERMINAL = BGPFlowSpecTrafficActionCommunity.TERMINAL
+
+# Constants for the VLAN Actions of Flow Specification.
+FLOWSPEC_VLAN_POP = BGPFlowSpecVlanActionCommunity.POP
+FLOWSPEC_VLAN_PUSH = BGPFlowSpecVlanActionCommunity.PUSH
+FLOWSPEC_VLAN_SWAP = BGPFlowSpecVlanActionCommunity.SWAP
+FLOWSPEC_VLAN_RW_INNER = BGPFlowSpecVlanActionCommunity.REWRITE_INNER
+FLOWSPEC_VLAN_RW_OUTER = BGPFlowSpecVlanActionCommunity.REWRITE_OUTER
+
+# Constants for the TPID Actions of Flow Specification.
+FLOWSPEC_TPID_TI = BGPFlowSpecTPIDActionCommunity.TI
+FLOWSPEC_TPID_TO = BGPFlowSpecTPIDActionCommunity.TO
+
+
+class EventPrefix(object):
+    """
+    Used to pass an update on any best remote path to
+    best_path_change_handler.
+
+    ================ ======================================================
+    Attribute        Description
+    ================ ======================================================
+    remote_as        The AS number of a peer that caused this change
+    route_dist       None in the case of IPv4 or IPv6 family
+    prefix           A prefix was changed
+    nexthop          The nexthop of the changed prefix
+    label            MPLS label for VPNv4, VPNv6 or EVPN prefix
+    path             An instance of ``info_base.base.Path`` subclass
+    is_withdraw      True if this prefix has gone otherwise False
+    ================ ======================================================
+    """
+
+    def __init__(self, path, is_withdraw):
+        self.path = path
+        self.is_withdraw = is_withdraw
+
+    @property
+    def remote_as(self):
+        return self.path.source.remote_as
+
+    @property
+    def route_dist(self):
+        if (isinstance(self.path, Vpnv4Path)
+                or isinstance(self.path, Vpnv6Path)
+                or isinstance(self.path, EvpnPath)):
+            return self.path.nlri.route_dist
+        else:
+            return None
+
+    @property
+    def prefix(self):
+        if isinstance(self.path, Ipv4Path) or isinstance(self.path, Ipv6Path):
+            return self.path.nlri.addr + '/' + str(self.path.nlri.length)
+        elif (isinstance(self.path, Vpnv4Path)
+              or isinstance(self.path, Vpnv6Path)
+              or isinstance(self.path, EvpnPath)):
+            return self.path.nlri.prefix
+        else:
+            return None
+
+    @property
+    def nexthop(self):
+        return self.path.nexthop
+
+    @property
+    def label(self):
+        if (isinstance(self.path, Vpnv4Path)
+                or isinstance(self.path, Vpnv6Path)
+                or isinstance(self.path, EvpnPath)):
+            return getattr(self.path.nlri, 'label_list', None)
+        else:
+            return None
+
+
+class BGPSpeaker(object):
+    """Class to provide the APIs of Ryu BGP Speaker.
+
+    ``as_number`` specifies an Autonomous Number. It must be an integer
+    between 1 and 65535.
+
+    ``router_id`` specifies BGP router identifier. It must be the
+    string representation of an IPv4 address (e.g. 10.0.0.1).
+
+    ``bgp_server_host`` specifies a list of TCP listen host addresses.
+
+    ``bgp_server_port`` specifies TCP listen port number. 179 is
+    used if not specified.
+
+    ``refresh_stalepath_time`` causes the BGP speaker to remove
+    stale routes from the BGP table after the timer expires, even
+    if the speaker does not receive a Router-Refresh End-of-RIB
+    message. This feature is disabled (not implemented yet).
+
+    ``refresh_max_eor_time`` causes the BGP speaker to generate a
+    Route-Refresh End-of-RIB message if it was not able to
+    generate one due to route flapping. This feature is disabled
+    (not implemented yet).
+
+    ``best_path_change_handler``, if specified, is called when any
+    best remote path is changed due to an update message or remote
+    peer down. The handler is supposed to take one argument, the
+    instance of an EventPrefix class instance.
+
+    ``adj_rib_in_change_handler``, if specified, is called when any
+    adj-RIB-in path is changed due to an update message or remote
+    peer down. The given handler should take three argument, the
+    instance of an EventPrefix class instance, str type peer's IP address
+    and int type peer's AS number.
+
+    ``peer_down_handler``, if specified, is called when BGP peering
+    session goes down.
+
+    ``peer_up_handler``, if specified, is called when BGP peering
+    session goes up.
+
+    ``ssh_console`` specifies whether or not SSH CLI need to be started.
+
+    ``ssh_port`` specifies the port number for SSH CLI server.
+    The default is bgp.operator.ssh.DEFAULT_SSH_PORT.
+
+    ``ssh_host`` specifies the IP address for SSH CLI server.
+    The default is bgp.operator.ssh.DEFAULT_SSH_HOST.
+
+    ``ssh_host_key`` specifies the path to the host key added to
+    the keys list used by SSH CLI server.
+    The default is bgp.operator.ssh.DEFAULT_SSH_HOST_KEY.
+
+    ``label_range`` specifies the range of MPLS labels generated
+    automatically.
+
+    ``allow_local_as_in_count`` maximum number of local AS number
+    occurrences in AS_PATH.  This option is useful for e.g.  auto RD/RT
+    configurations in leaf/spine architecture with shared AS numbers.
+    The default is 0 and means "local AS number is not allowed in
+    AS_PATH".  To allow local AS, 3 is recommended (Cisco's default).
+
+    ``cluster_id`` specifies the cluster identifier for Route Reflector.
+    It must be the string representation of an IPv4 address.
+    If omitted, "router_id" is used for this field.
+
+    ``local_pref`` specifies the default local preference. It must be an
+    integer.
+    """
+
+    def __init__(self, as_number, router_id,
+                 bgp_server_hosts=DEFAULT_BGP_SERVER_HOSTS,
+                 bgp_server_port=DEFAULT_BGP_SERVER_PORT,
+                 refresh_stalepath_time=DEFAULT_REFRESH_STALEPATH_TIME,
+                 refresh_max_eor_time=DEFAULT_REFRESH_MAX_EOR_TIME,
+                 best_path_change_handler=None,
+                 adj_rib_in_change_handler=None,
+                 peer_down_handler=None,
+                 peer_up_handler=None,
+                 ssh_console=False,
+                 ssh_port=None, ssh_host=None, ssh_host_key=None,
+                 label_range=DEFAULT_LABEL_RANGE,
+                 allow_local_as_in_count=0,
+                 cluster_id=None,
+                 local_pref=DEFAULT_LOCAL_PREF):
+        super(BGPSpeaker, self).__init__()
+
+        settings = {
+            LOCAL_AS: as_number,
+            ROUTER_ID: router_id,
+            BGP_SERVER_HOSTS: bgp_server_hosts,
+            BGP_SERVER_PORT: bgp_server_port,
+            REFRESH_STALEPATH_TIME: refresh_stalepath_time,
+            REFRESH_MAX_EOR_TIME: refresh_max_eor_time,
+            LABEL_RANGE: label_range,
+            ALLOW_LOCAL_AS_IN_COUNT: allow_local_as_in_count,
+            CLUSTER_ID: cluster_id,
+            LOCAL_PREF: local_pref,
+        }
+        self._core_start(settings)
+        self._init_signal_listeners()
+        self._best_path_change_handler = best_path_change_handler
+        self._adj_rib_in_change_handler = adj_rib_in_change_handler
+        self._peer_down_handler = peer_down_handler
+        self._peer_up_handler = peer_up_handler
+        if ssh_console:
+            # Note: paramiko used in bgp.operator.ssh is the optional
+            # requirements, imports bgp.operator.ssh here.
+            from ryu.services.protocols.bgp.operator import ssh
+            ssh_settings = {
+                ssh.SSH_PORT: ssh_port or ssh.DEFAULT_SSH_PORT,
+                ssh.SSH_HOST: ssh_host or ssh.DEFAULT_SSH_HOST,
+                ssh.SSH_HOST_KEY: ssh_host_key or ssh.DEFAULT_SSH_HOST_KEY,
+            }
+            hub.spawn(ssh.SSH_CLI_CONTROLLER.start, **ssh_settings)
+
+    def _notify_peer_down(self, peer):
+        remote_ip = peer.ip_address
+        remote_as = peer.remote_as
+        if self._peer_down_handler:
+            self._peer_down_handler(remote_ip, remote_as)
+
+    def _notify_peer_up(self, peer):
+        remote_ip = peer.protocol.recv_open_msg.bgp_identifier
+        remote_as = peer.protocol.recv_open_msg.my_as
+        if self._peer_up_handler:
+            self._peer_up_handler(remote_ip, remote_as)
+
+    def _notify_best_path_changed(self, path, is_withdraw):
+        if (not path.source
+                or not isinstance(path, (Ipv4Path, Ipv6Path,
+                                         Vpnv4Path, Vpnv6Path, EvpnPath))):
+            return
+
+        ev = EventPrefix(path, is_withdraw)
+
+        if self._best_path_change_handler:
+            self._best_path_change_handler(ev)
+
+    def _notify_adj_rib_in_changed(self, peer, route):
+        if not isinstance(route, ReceivedRoute):
+            return
+
+        if self._adj_rib_in_change_handler:
+            self._adj_rib_in_change_handler(
+                EventPrefix(route.path, route.path.is_withdraw),
+                peer.ip_address, peer.remote_as)
+
+    def _init_signal_listeners(self):
+        CORE_MANAGER.get_core_service()._signal_bus.register_listener(
+            BgpSignalBus.BGP_BEST_PATH_CHANGED,
+            lambda _, info:
+            self._notify_best_path_changed(info['path'],
+                                           info['is_withdraw'])
+        )
+        CORE_MANAGER.get_core_service()._signal_bus.register_listener(
+            BgpSignalBus.BGP_ADJ_RIB_IN_CHANGED,
+            lambda _, info:
+            self._notify_adj_rib_in_changed(info['peer'],
+                                            info['received_route'])
+        )
+        CORE_MANAGER.get_core_service()._signal_bus.register_listener(
+            BgpSignalBus.BGP_ADJ_DOWN,
+            lambda _, info:
+            self._notify_peer_down(info['peer'])
+        )
+        CORE_MANAGER.get_core_service()._signal_bus.register_listener(
+            BgpSignalBus.BGP_ADJ_UP,
+            lambda _, info:
+            self._notify_peer_up(info['peer'])
+        )
+
+    def _core_start(self, settings):
+        waiter = hub.Event()
+        call('core.start', waiter=waiter, **settings)
+        waiter.wait()
+
+    def _serve_forever(self):
+        pass
+
+    def shutdown(self):
+        """ Shutdown BGP speaker
+        """
+        call('core.stop')
+
+    def neighbor_add(self, address, remote_as,
+                     remote_port=DEFAULT_BGP_PORT,
+                     enable_ipv4=DEFAULT_CAP_MBGP_IPV4,
+                     enable_ipv6=DEFAULT_CAP_MBGP_IPV6,
+                     enable_vpnv4=DEFAULT_CAP_MBGP_VPNV4,
+                     enable_vpnv6=DEFAULT_CAP_MBGP_VPNV6,
+                     enable_evpn=DEFAULT_CAP_MBGP_EVPN,
+                     enable_ipv4fs=DEFAULT_CAP_MBGP_IPV4FS,
+                     enable_ipv6fs=DEFAULT_CAP_MBGP_IPV6FS,
+                     enable_vpnv4fs=DEFAULT_CAP_MBGP_VPNV4FS,
+                     enable_vpnv6fs=DEFAULT_CAP_MBGP_VPNV6FS,
+                     enable_l2vpnfs=DEFAULT_CAP_MBGP_L2VPNFS,
+                     enable_enhanced_refresh=DEFAULT_CAP_ENHANCED_REFRESH,
+                     enable_four_octet_as_number=DEFAULT_CAP_FOUR_OCTET_AS_NUMBER,
+                     next_hop=None, password=None, multi_exit_disc=None,
+                     site_of_origins=None,
+                     is_route_server_client=DEFAULT_IS_ROUTE_SERVER_CLIENT,
+                     is_route_reflector_client=DEFAULT_IS_ROUTE_REFLECTOR_CLIENT,
+                     is_next_hop_self=DEFAULT_IS_NEXT_HOP_SELF,
+                     local_address=None,
+                     local_port=None, local_as=None,
+                     connect_mode=DEFAULT_CONNECT_MODE):
+        """ This method registers a new neighbor. The BGP speaker tries to
+        establish a bgp session with the peer (accepts a connection
+        from the peer and also tries to connect to it).
+
+        ``address`` specifies the IP address of the peer. It must be
+        the string representation of an IP address. Only IPv4 is
+        supported now.
+
+        ``remote_as`` specifies the AS number of the peer. It must be
+        an integer between 1 and 65535.
+
+        ``remote_port`` specifies the TCP port number of the peer.
+
+        ``enable_ipv4`` enables IPv4 address family for this
+        neighbor.
+
+        ``enable_ipv6`` enables IPv6 address family for this
+        neighbor.
+
+        ``enable_vpnv4`` enables VPNv4 address family for this
+        neighbor.
+
+        ``enable_vpnv6`` enables VPNv6 address family for this
+        neighbor.
+
+        ``enable_evpn`` enables Ethernet VPN address family for this
+        neighbor.
+
+        ``enable_ipv4fs`` enables IPv4 Flow Specification address family
+        for this neighbor.
+
+        ``enable_ipv6fs`` enables IPv6 Flow Specification address family
+        for this neighbor.
+
+        ``enable_vpnv4fs`` enables VPNv4 Flow Specification address family
+        for this neighbor.
+
+        ``enable_vpnv6fs`` enables VPNv6 Flow Specification address family
+        for this neighbor.
+
+        ``enable_l2vpnfs`` enables L2VPN Flow Specification address family
+        for this neighbor.
+
+        ``enable_enhanced_refresh`` enables Enhanced Route Refresh for this
+        neighbor.
+
+        ``enable_four_octet_as_number`` enables Four-Octet AS Number
+        capability for this neighbor.
+
+        ``next_hop`` specifies the next hop IP address. If not
+        specified, host's ip address to access to a peer is used.
+
+        ``password`` is used for the MD5 authentication if it's
+        specified. By default, the MD5 authentication is disabled.
+
+        ``multi_exit_disc`` specifies multi exit discriminator (MED) value
+        as an int type value.
+        If omitted, MED is not sent to the neighbor.
+
+        ``site_of_origins`` specifies site_of_origin values.
+        This parameter must be a list of string.
+
+        ``is_route_server_client`` specifies whether this neighbor is a
+        router server's client or not.
+
+        ``is_route_reflector_client`` specifies whether this neighbor is a
+        router reflector's client or not.
+
+        ``is_next_hop_self`` specifies whether the BGP speaker announces
+        its own ip address to iBGP neighbor or not as path's next_hop address.
+
+        ``local_address`` specifies Loopback interface address for
+        iBGP peering.
+
+        ``local_port`` specifies source TCP port for iBGP peering.
+
+        ``local_as`` specifies local AS number per-peer.
+        If omitted, the AS number of BGPSpeaker instance is used.
+
+        ``connect_mode`` specifies how to connect to this neighbor.
+        This parameter must be one of the following.
+
+        - CONNECT_MODE_ACTIVE         = 'active'
+        - CONNECT_MODE_PASSIVE        = 'passive'
+        - CONNECT_MODE_BOTH (default) = 'both'
+        """
+        bgp_neighbor = {
+            neighbors.IP_ADDRESS: address,
+            neighbors.REMOTE_AS: remote_as,
+            REMOTE_PORT: remote_port,
+            PEER_NEXT_HOP: next_hop,
+            PASSWORD: password,
+            IS_ROUTE_SERVER_CLIENT: is_route_server_client,
+            IS_ROUTE_REFLECTOR_CLIENT: is_route_reflector_client,
+            IS_NEXT_HOP_SELF: is_next_hop_self,
+            CONNECT_MODE: connect_mode,
+            CAP_ENHANCED_REFRESH: enable_enhanced_refresh,
+            CAP_FOUR_OCTET_AS_NUMBER: enable_four_octet_as_number,
+            CAP_MBGP_IPV4: enable_ipv4,
+            CAP_MBGP_IPV6: enable_ipv6,
+            CAP_MBGP_VPNV4: enable_vpnv4,
+            CAP_MBGP_VPNV6: enable_vpnv6,
+            CAP_MBGP_EVPN: enable_evpn,
+            CAP_MBGP_IPV4FS: enable_ipv4fs,
+            CAP_MBGP_IPV6FS: enable_ipv6fs,
+            CAP_MBGP_VPNV4FS: enable_vpnv4fs,
+            CAP_MBGP_VPNV6FS: enable_vpnv6fs,
+            CAP_MBGP_L2VPNFS: enable_l2vpnfs,
+        }
+
+        if multi_exit_disc:
+            bgp_neighbor[MULTI_EXIT_DISC] = multi_exit_disc
+
+        if site_of_origins:
+            bgp_neighbor[SITE_OF_ORIGINS] = site_of_origins
+
+        if local_address:
+            bgp_neighbor[LOCAL_ADDRESS] = local_address
+
+        if local_port:
+            bgp_neighbor[LOCAL_PORT] = local_port
+
+        if local_as:
+            bgp_neighbor[LOCAL_AS] = local_as
+
+        call('neighbor.create', **bgp_neighbor)
+
+    def neighbor_del(self, address):
+        """ This method unregister the registered neighbor. If a session with
+        the peer exists, the session will be closed.
+
+        ``address`` specifies the IP address of the peer. It must be
+        the string representation of an IP address.
+        """
+        bgp_neighbor = {
+            neighbors.IP_ADDRESS: address,
+        }
+
+        call('neighbor.delete', **bgp_neighbor)
+
+    def neighbor_reset(self, address):
+        """ This method reset the registered neighbor.
+
+        ``address`` specifies the IP address of the peer. It must be
+        the string representation of an IP address.
+        """
+        bgp_neighbor = {
+            neighbors.IP_ADDRESS: address,
+        }
+
+        call('core.reset_neighbor', **bgp_neighbor)
+
+    def neighbor_update(self, address, conf_type, conf_value):
+        """ This method changes the neighbor configuration.
+
+        ``address`` specifies the IP address of the peer.
+
+        ``conf_type`` specifies configuration type which you want to change.
+        Currently ryu.services.protocols.bgp.bgpspeaker.MULTI_EXIT_DISC
+        can be specified.
+
+        ``conf_value`` specifies value for the configuration type.
+        """
+
+        assert conf_type == MULTI_EXIT_DISC or conf_type == CONNECT_MODE
+
+        func_name = 'neighbor.update'
+        attribute_param = {}
+        if conf_type == MULTI_EXIT_DISC:
+            attribute_param = {neighbors.MULTI_EXIT_DISC: conf_value}
+        elif conf_type == CONNECT_MODE:
+            attribute_param = {neighbors.CONNECT_MODE: conf_value}
+
+        param = {neighbors.IP_ADDRESS: address,
+                 neighbors.CHANGES: attribute_param}
+
+        call(func_name, **param)
+
+    def neighbor_state_get(self, address=None, format='json'):
+        """ This method returns the state of peer(s) in a json
+        format.
+
+        ``address`` specifies the address of a peer. If not given, the
+        state of all the peers return.
+
+        ``format`` specifies the format of the response.
+        This parameter must be one of the following.
+
+        - 'json' (default)
+        - 'cli'
+        """
+        show = {
+            'params': ['neighbor', 'summary'],
+            'format': format,
+        }
+        if address:
+            show['params'].append(address)
+
+        return call('operator.show', **show)
+
+    def prefix_add(self, prefix, next_hop=None, route_dist=None):
+        """ This method adds a new prefix to be advertised.
+
+        ``prefix`` must be the string representation of an IP network
+        (e.g., 10.1.1.0/24).
+
+        ``next_hop`` specifies the next hop address for this
+        prefix. This parameter is necessary for only VPNv4 and VPNv6
+        address families.
+
+        ``route_dist`` specifies a route distinguisher value. This
+        parameter is necessary for only VPNv4 and VPNv6 address
+        families.
+        """
+        func_name = 'network.add'
+        networks = {
+            PREFIX: prefix,
+        }
+        if next_hop:
+            networks[NEXT_HOP] = next_hop
+        if route_dist:
+            func_name = 'prefix.add_local'
+            networks[ROUTE_DISTINGUISHER] = route_dist
+
+            rf, p = self._check_rf_and_normalize(prefix)
+            networks[ROUTE_FAMILY] = rf
+            networks[PREFIX] = p
+
+            if rf == vrfs.VRF_RF_IPV6 and ip.valid_ipv4(next_hop):
+                # convert the next_hop to IPv4-Mapped IPv6 Address
+                networks[NEXT_HOP] = \
+                    str(netaddr.IPAddress(next_hop).ipv6())
+
+        return call(func_name, **networks)
+
+    def prefix_del(self, prefix, route_dist=None):
+        """ This method deletes a advertised prefix.
+
+        ``prefix`` must be the string representation of an IP network.
+
+        ``route_dist`` specifies a route distinguisher value.
+        """
+        func_name = 'network.del'
+        networks = {
+            PREFIX: prefix,
+        }
+        if route_dist:
+            func_name = 'prefix.delete_local'
+            networks[ROUTE_DISTINGUISHER] = route_dist
+
+            rf, p = self._check_rf_and_normalize(prefix)
+            networks[ROUTE_FAMILY] = rf
+            networks[PREFIX] = p
+
+        call(func_name, **networks)
+
+    def evpn_prefix_add(self, route_type, route_dist, esi=0,
+                        ethernet_tag_id=None, mac_addr=None, ip_addr=None,
+                        ip_prefix=None, gw_ip_addr=None, vni=None,
+                        next_hop=None, tunnel_type=None, pmsi_tunnel_type=None,
+                        redundancy_mode=None):
+        """ This method adds a new EVPN route to be advertised.
+
+        ``route_type`` specifies one of the EVPN route type name.
+        This parameter must be one of the following.
+
+        - EVPN_ETH_AUTO_DISCOVERY   = 'eth_ad'
+        - EVPN_MAC_IP_ADV_ROUTE     = 'mac_ip_adv'
+        - EVPN_MULTICAST_ETAG_ROUTE = 'multicast_etag'
+        - EVPN_ETH_SEGMENT          = 'eth_seg'
+        - EVPN_IP_PREFIX_ROUTE      = 'ip_prefix'
+
+        ``route_dist`` specifies a route distinguisher value.
+
+        ``esi`` is an value to specify the Ethernet Segment Identifier.
+        0 is the default and denotes a single-homed site.
+        If you want to advertise esi other than 0,
+        it must be set as dictionary type.
+        If esi is dictionary type, 'type' key must be set
+        and specifies ESI type.
+        For the supported ESI type, see :py:mod:`ryu.lib.packet.bgp.EvpnEsi`.
+        The remaining arguments are the same as that for
+        the corresponding class.
+
+        ``ethernet_tag_id`` specifies the Ethernet Tag ID.
+
+        ``mac_addr`` specifies a MAC address to advertise.
+
+        ``ip_addr`` specifies an IPv4 or IPv6 address to advertise.
+
+        ``ip_prefix`` specifies an IPv4 or IPv6 prefix to advertise.
+
+        ``gw_ip_addr`` specifies an IPv4 or IPv6 address of
+        gateway to advertise.
+
+        ``vni`` specifies an Virtual Network Identifier for VXLAN
+        or Virtual Subnet Identifier for NVGRE.
+        If tunnel_type is not TUNNEL_TYPE_VXLAN or TUNNEL_TYPE_NVGRE,
+        this field is ignored.
+
+        ``next_hop`` specifies the next hop address for this prefix.
+
+        ``tunnel_type`` specifies the data plane encapsulation type
+        to advertise. By the default, this attribute is not advertised.
+        The supported encapsulation types are following.
+
+        - TUNNEL_TYPE_VXLAN = 'vxlan'
+        - TUNNEL_TYPE_NVGRE = 'nvgre
+
+        ``pmsi_tunnel_type`` specifies the type of the PMSI tunnel attribute
+        used to encode the multicast tunnel identifier.
+        This attribute is advertised only if route_type is
+        EVPN_MULTICAST_ETAG_ROUTE and not advertised by the default.
+        This attribute can also carry vni if tunnel_type is specified.
+        The supported PMSI tunnel types are following.
+
+        - PMSI_TYPE_NO_TUNNEL_INFO = 0
+        - PMSI_TYPE_INGRESS_REP    = 6
+
+        ``redundancy_mode`` specifies a redundancy mode type.
+        This attribute is advertised only if route_type is
+        EVPN_ETH_AUTO_DISCOVERY and not advertised by the default.
+        The supported redundancy mode types are following.
+
+        - REDUNDANCY_MODE_ALL_ACTIVE    = 'all_active'
+        - REDUNDANCY_MODE_SINGLE_ACTIVE = 'single_active'
+        """
+        func_name = 'evpn_prefix.add_local'
+
+        # Check the default values
+        if not next_hop:
+            next_hop = '0.0.0.0'
+
+        # Set required arguments
+        kwargs = {EVPN_ROUTE_TYPE: route_type,
+                  ROUTE_DISTINGUISHER: route_dist,
+                  NEXT_HOP: next_hop}
+
+        # Set optional arguments
+        if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
+            kwargs[TUNNEL_TYPE] = tunnel_type
+        elif tunnel_type is not None:
+            raise ValueError('Unsupported tunnel type: %s' % tunnel_type)
+
+        # Set route type specific arguments
+        if route_type == EVPN_ETH_AUTO_DISCOVERY:
+            kwargs.update({
+                EVPN_ESI: esi,
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+            })
+            if vni is not None:
+                kwargs[EVPN_VNI] = vni
+            # Set Redundancy Mode Attribute arguments
+            if redundancy_mode in [
+                    REDUNDANCY_MODE_ALL_ACTIVE,
+                    REDUNDANCY_MODE_SINGLE_ACTIVE]:
+                kwargs[REDUNDANCY_MODE] = redundancy_mode
+            elif redundancy_mode is not None:
+                raise ValueError('Unsupported Redundancy Mode: %s' %
+                                 redundancy_mode)
+        elif route_type == EVPN_MAC_IP_ADV_ROUTE:
+            kwargs.update({
+                EVPN_ESI: esi,
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+                MAC_ADDR: mac_addr,
+                IP_ADDR: ip_addr,
+            })
+            # Set tunnel type specific arguments
+            if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
+                kwargs[EVPN_VNI] = vni
+        elif route_type == EVPN_MULTICAST_ETAG_ROUTE:
+            kwargs.update({
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+                IP_ADDR: ip_addr,
+            })
+            # Set tunnel type specific arguments
+            if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
+                kwargs[EVPN_VNI] = vni
+            # Set PMSI Tunnel Attribute arguments
+            if pmsi_tunnel_type in [
+                    PMSI_TYPE_NO_TUNNEL_INFO,
+                    PMSI_TYPE_INGRESS_REP]:
+                kwargs[PMSI_TUNNEL_TYPE] = pmsi_tunnel_type
+            elif pmsi_tunnel_type is not None:
+                raise ValueError('Unsupported PMSI tunnel type: %s' %
+                                 pmsi_tunnel_type)
+        elif route_type == EVPN_ETH_SEGMENT:
+            kwargs.update({
+                EVPN_ESI: esi,
+                IP_ADDR: ip_addr,
+            })
+        elif route_type == EVPN_IP_PREFIX_ROUTE:
+            kwargs.update({
+                EVPN_ESI: esi,
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+                IP_PREFIX: ip_prefix,
+                GW_IP_ADDR: gw_ip_addr,
+            })
+            # Set tunnel type specific arguments
+            if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
+                kwargs[EVPN_VNI] = vni
+        else:
+            raise ValueError('Unsupported EVPN route type: %s' % route_type)
+
+        call(func_name, **kwargs)
+
+    def evpn_prefix_del(self, route_type, route_dist, esi=0,
+                        ethernet_tag_id=None, mac_addr=None, ip_addr=None,
+                        ip_prefix=None):
+        """ This method deletes an advertised EVPN route.
+
+        ``route_type`` specifies one of the EVPN route type name.
+
+        ``route_dist`` specifies a route distinguisher value.
+
+        ``esi`` is an value to specify the Ethernet Segment Identifier.
+
+        ``ethernet_tag_id`` specifies the Ethernet Tag ID.
+
+        ``mac_addr`` specifies a MAC address to advertise.
+
+        ``ip_addr`` specifies an IPv4 or IPv6 address to advertise.
+
+        ``ip_prefix`` specifies an IPv4 or IPv6 prefix to advertise.
+        """
+        func_name = 'evpn_prefix.delete_local'
+
+        # Set required arguments
+        kwargs = {EVPN_ROUTE_TYPE: route_type,
+                  ROUTE_DISTINGUISHER: route_dist}
+
+        # Set route type specific arguments
+        if route_type == EVPN_ETH_AUTO_DISCOVERY:
+            kwargs.update({
+                EVPN_ESI: esi,
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+            })
+        elif route_type == EVPN_MAC_IP_ADV_ROUTE:
+            kwargs.update({
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+                MAC_ADDR: mac_addr,
+                IP_ADDR: ip_addr,
+            })
+        elif route_type == EVPN_MULTICAST_ETAG_ROUTE:
+            kwargs.update({
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+                IP_ADDR: ip_addr,
+            })
+        elif route_type == EVPN_ETH_SEGMENT:
+            kwargs.update({
+                EVPN_ESI: esi,
+                IP_ADDR: ip_addr,
+            })
+        elif route_type == EVPN_IP_PREFIX_ROUTE:
+            kwargs.update({
+                EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
+                IP_PREFIX: ip_prefix,
+            })
+        else:
+            raise ValueError('Unsupported EVPN route type: %s' % route_type)
+
+        call(func_name, **kwargs)
+
+    def flowspec_prefix_add(self, flowspec_family, rules, route_dist=None,
+                            actions=None):
+        """ This method adds a new Flow Specification prefix to be advertised.
+
+        ``flowspec_family`` specifies one of the flowspec family name.
+        This parameter must be one of the following.
+
+        - FLOWSPEC_FAMILY_IPV4  = 'ipv4fs'
+        - FLOWSPEC_FAMILY_IPV6  = 'ipv6fs'
+        - FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
+        - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
+        - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs'
+
+        ``rules`` specifies NLRIs of Flow Specification as
+        a dictionary type value.
+        For the supported NLRI types and arguments,
+        see `from_user()` method of the following classes.
+
+        - :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv4NLRI`
+        - :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv6NLRI`
+        - :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv4NLRI`
+        - :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv6NLRI`
+        - :py:mod:`ryu.lib.packet.bgp.FlowSpecL2VPNNLRI`
+
+        ``route_dist`` specifies a route distinguisher value.
+        This parameter is required only if flowspec_family is one of the
+        following address family.
+
+        - FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
+        - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
+        - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs'
+
+        ``actions`` specifies Traffic Filtering Actions of
+        Flow Specification as a dictionary type value.
+        The keys are "ACTION_NAME" for each action class and
+        values are used for the arguments to that class.
+        For the supported "ACTION_NAME" and arguments,
+        see the following table.
+
+        =============== ===============================================================
+        ACTION_NAME     Action Class
+        =============== ===============================================================
+        traffic_rate    :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficRateCommunity`
+        traffic_action  :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficActionCommunity`
+        redirect        :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecRedirectCommunity`
+        traffic_marking :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficMarkingCommunity`
+        vlan_action     :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecVlanActionCommunity`
+        tpid_action     :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTPIDActionCommunity`
+        =============== ===============================================================
+
+        Example(IPv4)::
+
+            >>> speaker = BGPSpeaker(as_number=65001, router_id='172.17.0.1')
+            >>> speaker.neighbor_add(address='172.17.0.2',
+            ...                      remote_as=65002,
+            ...                      enable_ipv4fs=True)
+            >>> speaker.flowspec_prefix_add(
+            ...     flowspec_family=FLOWSPEC_FAMILY_IPV4,
+            ...     rules={
+            ...         'dst_prefix': '10.60.1.0/24'
+            ...     },
+            ...     actions={
+            ...         'traffic_marking': {
+            ...             'dscp': 24
+            ...         }
+            ...     }
+            ... )
+
+        Example(VPNv4)::
+
+            >>> speaker = BGPSpeaker(as_number=65001, router_id='172.17.0.1')
+            >>> speaker.neighbor_add(address='172.17.0.2',
+            ...                      remote_as=65002,
+            ...                      enable_vpnv4fs=True)
+            >>> speaker.vrf_add(route_dist='65001:100',
+            ...                 import_rts=['65001:100'],
+            ...                 export_rts=['65001:100'],
+            ...                 route_family=RF_VPNV4_FLOWSPEC)
+            >>> speaker.flowspec_prefix_add(
+            ...     flowspec_family=FLOWSPEC_FAMILY_VPNV4,
+            ...     route_dist='65000:100',
+            ...     rules={
+            ...         'dst_prefix': '10.60.1.0/24'
+            ...     },
+            ...     actions={
+            ...         'traffic_marking': {
+            ...             'dscp': 24
+            ...         }
+            ...     }
+            ... )
+        """
+        func_name = 'flowspec.add'
+
+        # Set required arguments
+        kwargs = {
+            FLOWSPEC_FAMILY: flowspec_family,
+            FLOWSPEC_RULES: rules,
+            FLOWSPEC_ACTIONS: actions or {},
+        }
+
+        if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6,
+                               FLOWSPEC_FAMILY_L2VPN]:
+            func_name = 'flowspec.add_local'
+            kwargs.update({ROUTE_DISTINGUISHER: route_dist})
+
+        call(func_name, **kwargs)
+
+    def flowspec_prefix_del(self, flowspec_family, rules, route_dist=None):
+        """ This method deletes an advertised Flow Specification route.
+
+        ``flowspec_family`` specifies one of the flowspec family name.
+
+        ``rules`` specifies NLRIs of Flow Specification as
+        a dictionary type value.
+
+        ``route_dist`` specifies a route distinguisher value.
+        """
+        func_name = 'flowspec.del'
+
+        # Set required arguments
+        kwargs = {
+            FLOWSPEC_FAMILY: flowspec_family,
+            FLOWSPEC_RULES: rules,
+        }
+
+        if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6,
+                               FLOWSPEC_FAMILY_L2VPN]:
+            func_name = 'flowspec.del_local'
+            kwargs.update({ROUTE_DISTINGUISHER: route_dist})
+
+        call(func_name, **kwargs)
+
+    def vrf_add(self, route_dist, import_rts, export_rts, site_of_origins=None,
+                route_family=RF_VPN_V4, multi_exit_disc=None):
+        """ This method adds a new vrf used for VPN.
+
+        ``route_dist`` specifies a route distinguisher value.
+
+        ``import_rts`` specifies a list of route targets to be imported.
+
+        ``export_rts`` specifies a list of route targets to be exported.
+
+        ``site_of_origins`` specifies site_of_origin values.
+        This parameter must be a list of string.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be one of the following.
+
+        - RF_VPN_V4 (default) = 'ipv4'
+        - RF_VPN_V6           = 'ipv6'
+        - RF_L2_EVPN          = 'evpn'
+        - RF_VPNV4_FLOWSPEC   = 'ipv4fs'
+        - RF_VPNV6_FLOWSPEC   = 'ipv6fs'
+        - RF_L2VPN_FLOWSPEC   = 'l2vpnfs'
+
+        ``multi_exit_disc`` specifies multi exit discriminator (MED) value.
+        It must be an integer.
+        """
+        if route_family not in SUPPORTED_VRF_RF:
+            raise ValueError('Unsupported route_family: %s' % route_family)
+
+        vrf = {
+            vrfs.ROUTE_DISTINGUISHER: route_dist,
+            vrfs.IMPORT_RTS: import_rts,
+            vrfs.EXPORT_RTS: export_rts,
+            vrfs.SITE_OF_ORIGINS: site_of_origins,
+            vrfs.VRF_RF: route_family,
+            vrfs.MULTI_EXIT_DISC: multi_exit_disc,
+        }
+
+        call('vrf.create', **vrf)
+
+    def vrf_del(self, route_dist):
+        """ This method deletes the existing vrf.
+
+        ``route_dist`` specifies a route distinguisher value.
+        """
+
+        vrf = {vrfs.ROUTE_DISTINGUISHER: route_dist}
+
+        call('vrf.delete', **vrf)
+
+    def vrfs_get(self, subcommand='routes', route_dist=None,
+                 route_family='all', format='json'):
+        """ This method returns the existing vrfs.
+
+        ``subcommand`` specifies one of the following.
+
+        - 'routes': shows routes present for vrf
+        - 'summary': shows configuration and summary of vrf
+
+        ``route_dist`` specifies a route distinguisher value.
+        If route_family is not 'all', this value must be specified.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be one of the following.
+
+        - RF_VPN_V4  = 'ipv4'
+        - RF_VPN_V6  = 'ipv6'
+        - RF_L2_EVPN = 'evpn'
+        - 'all' (default)
+
+        ``format`` specifies the format of the response.
+        This parameter must be one of the following.
+
+        - 'json' (default)
+        - 'cli'
+        """
+        show = {
+            'format': format,
+        }
+        if route_family in SUPPORTED_VRF_RF:
+            assert route_dist is not None
+            show['params'] = ['vrf', subcommand, route_dist, route_family]
+        else:
+            show['params'] = ['vrf', subcommand, 'all']
+
+        return call('operator.show', **show)
+
+    def rib_get(self, family='all', format='json'):
+        """ This method returns the BGP routing information in a json
+        format. This will be improved soon.
+
+        ``family`` specifies the address family of the RIB (e.g. 'ipv4').
+
+        ``format`` specifies the format of the response.
+        This parameter must be one of the following.
+
+        - 'json' (default)
+        - 'cli'
+        """
+        show = {
+            'params': ['rib', family],
+            'format': format
+        }
+
+        return call('operator.show', **show)
+
+    def neighbor_get(self, route_type, address, format='json'):
+        """ This method returns the BGP adj-RIB-in/adj-RIB-out information
+        in a json format.
+
+        ``route_type`` This parameter is necessary for only received-routes
+        and sent-routes.
+
+        - received-routes : paths received and not withdrawn by given peer
+        - sent-routes : paths sent and not withdrawn to given peer
+
+        ``address`` specifies the IP address of the peer. It must be
+        the string representation of an IP address.
+
+        ``format`` specifies the format of the response.
+        This parameter must be one of the following.
+
+        - 'json' (default)
+        - 'cli'
+        """
+        show = {
+            'format': format,
+        }
+        if route_type == 'sent-routes' or route_type == 'received-routes':
+            show['params'] = ['neighbor', route_type, address, 'all']
+        else:
+            show['params'] = ['neighbor', 'received-routes', address, 'all']
+
+        return call('operator.show', **show)
+
+    def neighbors_get(self, format='json'):
+        """ This method returns a list of the BGP neighbors.
+
+        ``format`` specifies the format of the response.
+        This parameter must be one of the following.
+
+        - 'json' (default)
+        - 'cli'
+        """
+        show = {
+            'params': ['neighbor'],
+            'format': format,
+        }
+
+        return call('operator.show', **show)
+
+    def _set_filter(self, filter_type, address, filters):
+        assert filter_type in ('in', 'out'), (
+            "filter type must be 'in' or 'out'")
+
+        assert all(isinstance(f, Filter) for f in filters), (
+            'all the items in filters must be an instance of Filter sub-class')
+
+        if filters is None:
+            filters = []
+
+        func_name = 'neighbor.' + filter_type + '_filter.set'
+        param = {
+            neighbors.IP_ADDRESS: address,
+        }
+        if filter_type == 'in':
+            param[neighbors.IN_FILTER] = filters
+        else:
+            param[neighbors.OUT_FILTER] = filters
+
+        call(func_name, **param)
+
+    def out_filter_set(self, address, filters):
+        """ This method sets out-filter to neighbor.
+
+        ``address`` specifies the IP address of the peer.
+
+        ``filters`` specifies a filter list to filter the path advertisement.
+        The contents must be an instance of Filter sub-class
+
+        If you want to define out-filter that send only a particular
+        prefix to neighbor, filters can be created as follows::
+
+            p = PrefixFilter('10.5.111.0/24',
+                             policy=PrefixFilter.POLICY_PERMIT)
+
+            all = PrefixFilter('0.0.0.0/0',
+                               policy=PrefixFilter.POLICY_DENY)
+
+            pList = [p, all]
+
+            self.bgpspeaker.out_filter_set(neighbor_address, pList)
+
+        .. Note::
+
+            out-filter evaluates paths in the order of Filter in the pList.
+        """
+
+        self._set_filter('out', address, filters)
+
+    def out_filter_get(self, address):
+        """ This method gets out-filter setting from the specified neighbor.
+
+        ``address`` specifies the IP address of the peer.
+
+        Returns a list object containing an instance of Filter sub-class
+        """
+
+        func_name = 'neighbor.out_filter.get'
+        param = {
+            neighbors.IP_ADDRESS: address,
+        }
+
+        return call(func_name, **param)
+
+    def in_filter_set(self, address, filters):
+        """This method sets in-bound filters to a neighbor.
+
+        ``address`` specifies the IP address of the neighbor
+
+        ``filters`` specifies filter list applied before advertised paths are
+        imported to the global rib. All the items in the list must be an
+        instance of Filter sub-class.
+        """
+
+        self._set_filter('in', address, filters)
+
+    def in_filter_get(self, address):
+        """This method gets in-bound filters of the specified neighbor.
+
+        ``address`` specifies the IP address of the neighbor.
+
+        Returns a list object containing an instance of Filter sub-class
+        """
+
+        func_name = 'neighbor.in_filter.get'
+        param = {
+            neighbors.IP_ADDRESS: address,
+        }
+
+        return call(func_name, **param)
+
+    def bmp_server_add(self, address, port):
+        """This method registers a new BMP (BGP monitoring Protocol)
+        server. The BGP speaker starts to send BMP messages to the
+        server. Currently, only one BMP server can be registered.
+
+        ``address`` specifies the IP address of a BMP server.
+
+        ``port`` specifies the listen port number of a BMP server.
+        """
+
+        func_name = 'bmp.start'
+        param = {
+            'host': address,
+            'port': port,
+        }
+
+        call(func_name, **param)
+
+    def bmp_server_del(self, address, port):
+        """ This method unregister the registered BMP server.
+
+        ``address`` specifies the IP address of a BMP server.
+
+        ``port`` specifies the listen port number of a BMP server.
+        """
+
+        func_name = 'bmp.stop'
+        param = {
+            'host': address,
+            'port': port,
+        }
+
+        call(func_name, **param)
+
+    def attribute_map_set(self, address, attribute_maps,
+                          route_dist=None, route_family=RF_VPN_V4):
+        """This method sets attribute mapping to a neighbor.
+        attribute mapping can be used when you want to apply
+        attribute to BGPUpdate under specific conditions.
+
+        ``address`` specifies the IP address of the neighbor
+
+        ``attribute_maps`` specifies attribute_map list that are used
+        before paths are advertised. All the items in the list must
+        be an instance of AttributeMap class
+
+        ``route_dist`` specifies route dist in which attribute_maps
+        are added.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be one of the following.
+
+        - RF_VPN_V4 (default) = 'ipv4'
+        - RF_VPN_V6           = 'ipv6'
+
+        We can set AttributeMap to a neighbor as follows::
+
+            pref_filter = PrefixFilter('192.168.103.0/30',
+                                       PrefixFilter.POLICY_PERMIT)
+
+            attribute_map = AttributeMap([pref_filter],
+                                         AttributeMap.ATTR_LOCAL_PREF, 250)
+
+            speaker.attribute_map_set('192.168.50.102', [attribute_map])
+        """
+
+        if route_family not in SUPPORTED_VRF_RF:
+            raise ValueError('Unsupported route_family: %s' % route_family)
+
+        func_name = 'neighbor.attribute_map.set'
+        param = {
+            neighbors.IP_ADDRESS: address,
+            neighbors.ATTRIBUTE_MAP: attribute_maps,
+        }
+        if route_dist is not None:
+            param[vrfs.ROUTE_DISTINGUISHER] = route_dist
+            param[vrfs.VRF_RF] = route_family
+
+        call(func_name, **param)
+
+    def attribute_map_get(self, address, route_dist=None,
+                          route_family=RF_VPN_V4):
+        """This method gets in-bound filters of the specified neighbor.
+
+        ``address`` specifies the IP address of the neighbor.
+
+        ``route_dist`` specifies route distinguisher that has attribute_maps.
+
+        ``route_family`` specifies route family of the VRF.
+        This parameter must be one of the following.
+
+        - RF_VPN_V4 (default) = 'ipv4'
+        - RF_VPN_V6           = 'ipv6'
+
+        Returns a list object containing an instance of AttributeMap
+        """
+
+        if route_family not in SUPPORTED_VRF_RF:
+            raise ValueError('Unsupported route_family: %s' % route_family)
+
+        func_name = 'neighbor.attribute_map.get'
+        param = {
+            neighbors.IP_ADDRESS: address,
+        }
+        if route_dist is not None:
+            param[vrfs.ROUTE_DISTINGUISHER] = route_dist
+            param[vrfs.VRF_RF] = route_family
+
+        return call(func_name, **param)
+
+    @staticmethod
+    def _check_rf_and_normalize(prefix):
+        """ check prefix's route_family and if the address is
+        IPv6 address, return IPv6 route_family and normalized IPv6 address.
+        If the address is IPv4 address, return IPv4 route_family
+        and the prefix itself.
+        """
+        addr, masklen = prefix.split('/')
+        if ip.valid_ipv6(addr):
+            # normalize IPv6 address
+            ipv6_prefix = str(netaddr.IPAddress(addr)) + '/' + masklen
+            return vrfs.VRF_RF_IPV6, ipv6_prefix
+        else:
+            return vrfs.VRF_RF_IPV4, prefix