backing up
[vsorcdistro/.git] / ryu / build / lib.linux-armv7l-2.7 / ryu / services / protocols / bgp / bgpspeaker.py
1 # Copyright (C) 2014 Nippon Telegraph and Telephone Corporation.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 #    http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12 # implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15 """This module offers a class to enable your code to speak BGP protocol.
16
17 """
18
19 import netaddr
20 from ryu.lib import hub
21 from ryu.lib import ip
22 from ryu.lib.packet.bgp import (
23     BGPFlowSpecTrafficActionCommunity,
24     BGPFlowSpecVlanActionCommunity,
25     BGPFlowSpecTPIDActionCommunity,
26 )
27
28 from ryu.services.protocols.bgp.core_manager import CORE_MANAGER
29 from ryu.services.protocols.bgp.signals.emit import BgpSignalBus
30 from ryu.services.protocols.bgp.api.base import call
31 from ryu.services.protocols.bgp.api.base import PREFIX
32 from ryu.services.protocols.bgp.api.base import EVPN_ROUTE_TYPE
33 from ryu.services.protocols.bgp.api.base import EVPN_ESI
34 from ryu.services.protocols.bgp.api.base import EVPN_ETHERNET_TAG_ID
35 from ryu.services.protocols.bgp.api.base import REDUNDANCY_MODE
36 from ryu.services.protocols.bgp.api.base import IP_ADDR
37 from ryu.services.protocols.bgp.api.base import MAC_ADDR
38 from ryu.services.protocols.bgp.api.base import NEXT_HOP
39 from ryu.services.protocols.bgp.api.base import IP_PREFIX
40 from ryu.services.protocols.bgp.api.base import GW_IP_ADDR
41 from ryu.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER
42 from ryu.services.protocols.bgp.api.base import ROUTE_FAMILY
43 from ryu.services.protocols.bgp.api.base import EVPN_VNI
44 from ryu.services.protocols.bgp.api.base import TUNNEL_TYPE
45 from ryu.services.protocols.bgp.api.base import PMSI_TUNNEL_TYPE
46 from ryu.services.protocols.bgp.api.prefix import EVPN_MAX_ET
47 from ryu.services.protocols.bgp.api.prefix import ESI_TYPE_LACP
48 from ryu.services.protocols.bgp.api.prefix import ESI_TYPE_L2_BRIDGE
49 from ryu.services.protocols.bgp.api.prefix import ESI_TYPE_MAC_BASED
50 from ryu.services.protocols.bgp.api.prefix import EVPN_ETH_AUTO_DISCOVERY
51 from ryu.services.protocols.bgp.api.prefix import EVPN_MAC_IP_ADV_ROUTE
52 from ryu.services.protocols.bgp.api.prefix import EVPN_MULTICAST_ETAG_ROUTE
53 from ryu.services.protocols.bgp.api.prefix import EVPN_ETH_SEGMENT
54 from ryu.services.protocols.bgp.api.prefix import EVPN_IP_PREFIX_ROUTE
55 from ryu.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_ALL_ACTIVE
56 from ryu.services.protocols.bgp.api.prefix import REDUNDANCY_MODE_SINGLE_ACTIVE
57 from ryu.services.protocols.bgp.api.prefix import TUNNEL_TYPE_VXLAN
58 from ryu.services.protocols.bgp.api.prefix import TUNNEL_TYPE_NVGRE
59 from ryu.services.protocols.bgp.api.prefix import (
60     PMSI_TYPE_NO_TUNNEL_INFO,
61     PMSI_TYPE_INGRESS_REP)
62 from ryu.services.protocols.bgp.api.prefix import (
63     FLOWSPEC_FAMILY,
64     FLOWSPEC_FAMILY_IPV4,
65     FLOWSPEC_FAMILY_VPNV4,
66     FLOWSPEC_FAMILY_IPV6,
67     FLOWSPEC_FAMILY_VPNV6,
68     FLOWSPEC_FAMILY_L2VPN,
69     FLOWSPEC_RULES,
70     FLOWSPEC_ACTIONS)
71 from ryu.services.protocols.bgp.model import ReceivedRoute
72 from ryu.services.protocols.bgp.rtconf.common import LOCAL_AS
73 from ryu.services.protocols.bgp.rtconf.common import ROUTER_ID
74 from ryu.services.protocols.bgp.rtconf.common import CLUSTER_ID
75 from ryu.services.protocols.bgp.rtconf.common import BGP_SERVER_HOSTS
76 from ryu.services.protocols.bgp.rtconf.common import BGP_SERVER_PORT
77 from ryu.services.protocols.bgp.rtconf.common import DEFAULT_BGP_SERVER_HOSTS
78 from ryu.services.protocols.bgp.rtconf.common import DEFAULT_BGP_SERVER_PORT
79 from ryu.services.protocols.bgp.rtconf.common import (
80     DEFAULT_REFRESH_MAX_EOR_TIME, DEFAULT_REFRESH_STALEPATH_TIME)
81 from ryu.services.protocols.bgp.rtconf.common import DEFAULT_LABEL_RANGE
82 from ryu.services.protocols.bgp.rtconf.common import REFRESH_MAX_EOR_TIME
83 from ryu.services.protocols.bgp.rtconf.common import REFRESH_STALEPATH_TIME
84 from ryu.services.protocols.bgp.rtconf.common import LABEL_RANGE
85 from ryu.services.protocols.bgp.rtconf.common import ALLOW_LOCAL_AS_IN_COUNT
86 from ryu.services.protocols.bgp.rtconf.common import LOCAL_PREF
87 from ryu.services.protocols.bgp.rtconf.common import DEFAULT_LOCAL_PREF
88 from ryu.services.protocols.bgp.rtconf import neighbors
89 from ryu.services.protocols.bgp.rtconf import vrfs
90 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4
91 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6
92 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4
93 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6
94 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_EVPN
95 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV4FS
96 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_IPV6FS
97 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV4FS
98 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_VPNV6FS
99 from ryu.services.protocols.bgp.rtconf.base import CAP_MBGP_L2VPNFS
100 from ryu.services.protocols.bgp.rtconf.base import CAP_ENHANCED_REFRESH
101 from ryu.services.protocols.bgp.rtconf.base import CAP_FOUR_OCTET_AS_NUMBER
102 from ryu.services.protocols.bgp.rtconf.base import MULTI_EXIT_DISC
103 from ryu.services.protocols.bgp.rtconf.base import SITE_OF_ORIGINS
104 from ryu.services.protocols.bgp.rtconf.neighbors import (
105     DEFAULT_CAP_MBGP_IPV4,
106     DEFAULT_CAP_MBGP_IPV6,
107     DEFAULT_CAP_MBGP_VPNV4,
108     DEFAULT_CAP_MBGP_VPNV6,
109     DEFAULT_CAP_MBGP_EVPN,
110     DEFAULT_CAP_MBGP_IPV4FS,
111     DEFAULT_CAP_MBGP_IPV6FS,
112     DEFAULT_CAP_MBGP_VPNV4FS,
113     DEFAULT_CAP_MBGP_VPNV6FS,
114     DEFAULT_CAP_MBGP_L2VPNFS,
115     DEFAULT_CAP_ENHANCED_REFRESH,
116     DEFAULT_CAP_FOUR_OCTET_AS_NUMBER,
117     DEFAULT_CONNECT_MODE,
118     REMOTE_PORT,
119     DEFAULT_BGP_PORT,
120     PEER_NEXT_HOP,
121     PASSWORD,
122     DEFAULT_IS_ROUTE_SERVER_CLIENT,
123     IS_ROUTE_SERVER_CLIENT,
124     DEFAULT_IS_ROUTE_REFLECTOR_CLIENT,
125     IS_ROUTE_REFLECTOR_CLIENT,
126     DEFAULT_IS_NEXT_HOP_SELF,
127     IS_NEXT_HOP_SELF,
128     CONNECT_MODE,
129     LOCAL_ADDRESS,
130     LOCAL_PORT,
131 )
132 from ryu.services.protocols.bgp.rtconf.vrfs import SUPPORTED_VRF_RF
133 from ryu.services.protocols.bgp.info_base.base import Filter
134 from ryu.services.protocols.bgp.info_base.ipv4 import Ipv4Path
135 from ryu.services.protocols.bgp.info_base.ipv6 import Ipv6Path
136 from ryu.services.protocols.bgp.info_base.vpnv4 import Vpnv4Path
137 from ryu.services.protocols.bgp.info_base.vpnv6 import Vpnv6Path
138 from ryu.services.protocols.bgp.info_base.evpn import EvpnPath
139
140
141 NEIGHBOR_CONF_MED = MULTI_EXIT_DISC  # for backward compatibility
142 RF_VPN_V4 = vrfs.VRF_RF_IPV4
143 RF_VPN_V6 = vrfs.VRF_RF_IPV6
144 RF_L2_EVPN = vrfs.VRF_RF_L2_EVPN
145 RF_VPNV4_FLOWSPEC = vrfs.VRF_RF_IPV4_FLOWSPEC
146 RF_VPNV6_FLOWSPEC = vrfs.VRF_RF_IPV6_FLOWSPEC
147 RF_L2VPN_FLOWSPEC = vrfs.VRF_RF_L2VPN_FLOWSPEC
148
149 # Constants for the Traffic Filtering Actions of Flow Specification.
150 FLOWSPEC_TA_SAMPLE = BGPFlowSpecTrafficActionCommunity.SAMPLE
151 FLOWSPEC_TA_TERMINAL = BGPFlowSpecTrafficActionCommunity.TERMINAL
152
153 # Constants for the VLAN Actions of Flow Specification.
154 FLOWSPEC_VLAN_POP = BGPFlowSpecVlanActionCommunity.POP
155 FLOWSPEC_VLAN_PUSH = BGPFlowSpecVlanActionCommunity.PUSH
156 FLOWSPEC_VLAN_SWAP = BGPFlowSpecVlanActionCommunity.SWAP
157 FLOWSPEC_VLAN_RW_INNER = BGPFlowSpecVlanActionCommunity.REWRITE_INNER
158 FLOWSPEC_VLAN_RW_OUTER = BGPFlowSpecVlanActionCommunity.REWRITE_OUTER
159
160 # Constants for the TPID Actions of Flow Specification.
161 FLOWSPEC_TPID_TI = BGPFlowSpecTPIDActionCommunity.TI
162 FLOWSPEC_TPID_TO = BGPFlowSpecTPIDActionCommunity.TO
163
164
165 class EventPrefix(object):
166     """
167     Used to pass an update on any best remote path to
168     best_path_change_handler.
169
170     ================ ======================================================
171     Attribute        Description
172     ================ ======================================================
173     remote_as        The AS number of a peer that caused this change
174     route_dist       None in the case of IPv4 or IPv6 family
175     prefix           A prefix was changed
176     nexthop          The nexthop of the changed prefix
177     label            MPLS label for VPNv4, VPNv6 or EVPN prefix
178     path             An instance of ``info_base.base.Path`` subclass
179     is_withdraw      True if this prefix has gone otherwise False
180     ================ ======================================================
181     """
182
183     def __init__(self, path, is_withdraw):
184         self.path = path
185         self.is_withdraw = is_withdraw
186
187     @property
188     def remote_as(self):
189         return self.path.source.remote_as
190
191     @property
192     def route_dist(self):
193         if (isinstance(self.path, Vpnv4Path)
194                 or isinstance(self.path, Vpnv6Path)
195                 or isinstance(self.path, EvpnPath)):
196             return self.path.nlri.route_dist
197         else:
198             return None
199
200     @property
201     def prefix(self):
202         if isinstance(self.path, Ipv4Path) or isinstance(self.path, Ipv6Path):
203             return self.path.nlri.addr + '/' + str(self.path.nlri.length)
204         elif (isinstance(self.path, Vpnv4Path)
205               or isinstance(self.path, Vpnv6Path)
206               or isinstance(self.path, EvpnPath)):
207             return self.path.nlri.prefix
208         else:
209             return None
210
211     @property
212     def nexthop(self):
213         return self.path.nexthop
214
215     @property
216     def label(self):
217         if (isinstance(self.path, Vpnv4Path)
218                 or isinstance(self.path, Vpnv6Path)
219                 or isinstance(self.path, EvpnPath)):
220             return getattr(self.path.nlri, 'label_list', None)
221         else:
222             return None
223
224
225 class BGPSpeaker(object):
226     """Class to provide the APIs of Ryu BGP Speaker.
227
228     ``as_number`` specifies an Autonomous Number. It must be an integer
229     between 1 and 65535.
230
231     ``router_id`` specifies BGP router identifier. It must be the
232     string representation of an IPv4 address (e.g. 10.0.0.1).
233
234     ``bgp_server_host`` specifies a list of TCP listen host addresses.
235
236     ``bgp_server_port`` specifies TCP listen port number. 179 is
237     used if not specified.
238
239     ``refresh_stalepath_time`` causes the BGP speaker to remove
240     stale routes from the BGP table after the timer expires, even
241     if the speaker does not receive a Router-Refresh End-of-RIB
242     message. This feature is disabled (not implemented yet).
243
244     ``refresh_max_eor_time`` causes the BGP speaker to generate a
245     Route-Refresh End-of-RIB message if it was not able to
246     generate one due to route flapping. This feature is disabled
247     (not implemented yet).
248
249     ``best_path_change_handler``, if specified, is called when any
250     best remote path is changed due to an update message or remote
251     peer down. The handler is supposed to take one argument, the
252     instance of an EventPrefix class instance.
253
254     ``adj_rib_in_change_handler``, if specified, is called when any
255     adj-RIB-in path is changed due to an update message or remote
256     peer down. The given handler should take three argument, the
257     instance of an EventPrefix class instance, str type peer's IP address
258     and int type peer's AS number.
259
260     ``peer_down_handler``, if specified, is called when BGP peering
261     session goes down.
262
263     ``peer_up_handler``, if specified, is called when BGP peering
264     session goes up.
265
266     ``ssh_console`` specifies whether or not SSH CLI need to be started.
267
268     ``ssh_port`` specifies the port number for SSH CLI server.
269     The default is bgp.operator.ssh.DEFAULT_SSH_PORT.
270
271     ``ssh_host`` specifies the IP address for SSH CLI server.
272     The default is bgp.operator.ssh.DEFAULT_SSH_HOST.
273
274     ``ssh_host_key`` specifies the path to the host key added to
275     the keys list used by SSH CLI server.
276     The default is bgp.operator.ssh.DEFAULT_SSH_HOST_KEY.
277
278     ``label_range`` specifies the range of MPLS labels generated
279     automatically.
280
281     ``allow_local_as_in_count`` maximum number of local AS number
282     occurrences in AS_PATH.  This option is useful for e.g.  auto RD/RT
283     configurations in leaf/spine architecture with shared AS numbers.
284     The default is 0 and means "local AS number is not allowed in
285     AS_PATH".  To allow local AS, 3 is recommended (Cisco's default).
286
287     ``cluster_id`` specifies the cluster identifier for Route Reflector.
288     It must be the string representation of an IPv4 address.
289     If omitted, "router_id" is used for this field.
290
291     ``local_pref`` specifies the default local preference. It must be an
292     integer.
293     """
294
295     def __init__(self, as_number, router_id,
296                  bgp_server_hosts=DEFAULT_BGP_SERVER_HOSTS,
297                  bgp_server_port=DEFAULT_BGP_SERVER_PORT,
298                  refresh_stalepath_time=DEFAULT_REFRESH_STALEPATH_TIME,
299                  refresh_max_eor_time=DEFAULT_REFRESH_MAX_EOR_TIME,
300                  best_path_change_handler=None,
301                  adj_rib_in_change_handler=None,
302                  peer_down_handler=None,
303                  peer_up_handler=None,
304                  ssh_console=False,
305                  ssh_port=None, ssh_host=None, ssh_host_key=None,
306                  label_range=DEFAULT_LABEL_RANGE,
307                  allow_local_as_in_count=0,
308                  cluster_id=None,
309                  local_pref=DEFAULT_LOCAL_PREF):
310         super(BGPSpeaker, self).__init__()
311
312         settings = {
313             LOCAL_AS: as_number,
314             ROUTER_ID: router_id,
315             BGP_SERVER_HOSTS: bgp_server_hosts,
316             BGP_SERVER_PORT: bgp_server_port,
317             REFRESH_STALEPATH_TIME: refresh_stalepath_time,
318             REFRESH_MAX_EOR_TIME: refresh_max_eor_time,
319             LABEL_RANGE: label_range,
320             ALLOW_LOCAL_AS_IN_COUNT: allow_local_as_in_count,
321             CLUSTER_ID: cluster_id,
322             LOCAL_PREF: local_pref,
323         }
324         self._core_start(settings)
325         self._init_signal_listeners()
326         self._best_path_change_handler = best_path_change_handler
327         self._adj_rib_in_change_handler = adj_rib_in_change_handler
328         self._peer_down_handler = peer_down_handler
329         self._peer_up_handler = peer_up_handler
330         if ssh_console:
331             # Note: paramiko used in bgp.operator.ssh is the optional
332             # requirements, imports bgp.operator.ssh here.
333             from ryu.services.protocols.bgp.operator import ssh
334             ssh_settings = {
335                 ssh.SSH_PORT: ssh_port or ssh.DEFAULT_SSH_PORT,
336                 ssh.SSH_HOST: ssh_host or ssh.DEFAULT_SSH_HOST,
337                 ssh.SSH_HOST_KEY: ssh_host_key or ssh.DEFAULT_SSH_HOST_KEY,
338             }
339             hub.spawn(ssh.SSH_CLI_CONTROLLER.start, **ssh_settings)
340
341     def _notify_peer_down(self, peer):
342         remote_ip = peer.ip_address
343         remote_as = peer.remote_as
344         if self._peer_down_handler:
345             self._peer_down_handler(remote_ip, remote_as)
346
347     def _notify_peer_up(self, peer):
348         remote_ip = peer.protocol.recv_open_msg.bgp_identifier
349         remote_as = peer.protocol.recv_open_msg.my_as
350         if self._peer_up_handler:
351             self._peer_up_handler(remote_ip, remote_as)
352
353     def _notify_best_path_changed(self, path, is_withdraw):
354         if (not path.source
355                 or not isinstance(path, (Ipv4Path, Ipv6Path,
356                                          Vpnv4Path, Vpnv6Path, EvpnPath))):
357             return
358
359         ev = EventPrefix(path, is_withdraw)
360
361         if self._best_path_change_handler:
362             self._best_path_change_handler(ev)
363
364     def _notify_adj_rib_in_changed(self, peer, route):
365         if not isinstance(route, ReceivedRoute):
366             return
367
368         if self._adj_rib_in_change_handler:
369             self._adj_rib_in_change_handler(
370                 EventPrefix(route.path, route.path.is_withdraw),
371                 peer.ip_address, peer.remote_as)
372
373     def _init_signal_listeners(self):
374         CORE_MANAGER.get_core_service()._signal_bus.register_listener(
375             BgpSignalBus.BGP_BEST_PATH_CHANGED,
376             lambda _, info:
377             self._notify_best_path_changed(info['path'],
378                                            info['is_withdraw'])
379         )
380         CORE_MANAGER.get_core_service()._signal_bus.register_listener(
381             BgpSignalBus.BGP_ADJ_RIB_IN_CHANGED,
382             lambda _, info:
383             self._notify_adj_rib_in_changed(info['peer'],
384                                             info['received_route'])
385         )
386         CORE_MANAGER.get_core_service()._signal_bus.register_listener(
387             BgpSignalBus.BGP_ADJ_DOWN,
388             lambda _, info:
389             self._notify_peer_down(info['peer'])
390         )
391         CORE_MANAGER.get_core_service()._signal_bus.register_listener(
392             BgpSignalBus.BGP_ADJ_UP,
393             lambda _, info:
394             self._notify_peer_up(info['peer'])
395         )
396
397     def _core_start(self, settings):
398         waiter = hub.Event()
399         call('core.start', waiter=waiter, **settings)
400         waiter.wait()
401
402     def _serve_forever(self):
403         pass
404
405     def shutdown(self):
406         """ Shutdown BGP speaker
407         """
408         call('core.stop')
409
410     def neighbor_add(self, address, remote_as,
411                      remote_port=DEFAULT_BGP_PORT,
412                      enable_ipv4=DEFAULT_CAP_MBGP_IPV4,
413                      enable_ipv6=DEFAULT_CAP_MBGP_IPV6,
414                      enable_vpnv4=DEFAULT_CAP_MBGP_VPNV4,
415                      enable_vpnv6=DEFAULT_CAP_MBGP_VPNV6,
416                      enable_evpn=DEFAULT_CAP_MBGP_EVPN,
417                      enable_ipv4fs=DEFAULT_CAP_MBGP_IPV4FS,
418                      enable_ipv6fs=DEFAULT_CAP_MBGP_IPV6FS,
419                      enable_vpnv4fs=DEFAULT_CAP_MBGP_VPNV4FS,
420                      enable_vpnv6fs=DEFAULT_CAP_MBGP_VPNV6FS,
421                      enable_l2vpnfs=DEFAULT_CAP_MBGP_L2VPNFS,
422                      enable_enhanced_refresh=DEFAULT_CAP_ENHANCED_REFRESH,
423                      enable_four_octet_as_number=DEFAULT_CAP_FOUR_OCTET_AS_NUMBER,
424                      next_hop=None, password=None, multi_exit_disc=None,
425                      site_of_origins=None,
426                      is_route_server_client=DEFAULT_IS_ROUTE_SERVER_CLIENT,
427                      is_route_reflector_client=DEFAULT_IS_ROUTE_REFLECTOR_CLIENT,
428                      is_next_hop_self=DEFAULT_IS_NEXT_HOP_SELF,
429                      local_address=None,
430                      local_port=None, local_as=None,
431                      connect_mode=DEFAULT_CONNECT_MODE):
432         """ This method registers a new neighbor. The BGP speaker tries to
433         establish a bgp session with the peer (accepts a connection
434         from the peer and also tries to connect to it).
435
436         ``address`` specifies the IP address of the peer. It must be
437         the string representation of an IP address. Only IPv4 is
438         supported now.
439
440         ``remote_as`` specifies the AS number of the peer. It must be
441         an integer between 1 and 65535.
442
443         ``remote_port`` specifies the TCP port number of the peer.
444
445         ``enable_ipv4`` enables IPv4 address family for this
446         neighbor.
447
448         ``enable_ipv6`` enables IPv6 address family for this
449         neighbor.
450
451         ``enable_vpnv4`` enables VPNv4 address family for this
452         neighbor.
453
454         ``enable_vpnv6`` enables VPNv6 address family for this
455         neighbor.
456
457         ``enable_evpn`` enables Ethernet VPN address family for this
458         neighbor.
459
460         ``enable_ipv4fs`` enables IPv4 Flow Specification address family
461         for this neighbor.
462
463         ``enable_ipv6fs`` enables IPv6 Flow Specification address family
464         for this neighbor.
465
466         ``enable_vpnv4fs`` enables VPNv4 Flow Specification address family
467         for this neighbor.
468
469         ``enable_vpnv6fs`` enables VPNv6 Flow Specification address family
470         for this neighbor.
471
472         ``enable_l2vpnfs`` enables L2VPN Flow Specification address family
473         for this neighbor.
474
475         ``enable_enhanced_refresh`` enables Enhanced Route Refresh for this
476         neighbor.
477
478         ``enable_four_octet_as_number`` enables Four-Octet AS Number
479         capability for this neighbor.
480
481         ``next_hop`` specifies the next hop IP address. If not
482         specified, host's ip address to access to a peer is used.
483
484         ``password`` is used for the MD5 authentication if it's
485         specified. By default, the MD5 authentication is disabled.
486
487         ``multi_exit_disc`` specifies multi exit discriminator (MED) value
488         as an int type value.
489         If omitted, MED is not sent to the neighbor.
490
491         ``site_of_origins`` specifies site_of_origin values.
492         This parameter must be a list of string.
493
494         ``is_route_server_client`` specifies whether this neighbor is a
495         router server's client or not.
496
497         ``is_route_reflector_client`` specifies whether this neighbor is a
498         router reflector's client or not.
499
500         ``is_next_hop_self`` specifies whether the BGP speaker announces
501         its own ip address to iBGP neighbor or not as path's next_hop address.
502
503         ``local_address`` specifies Loopback interface address for
504         iBGP peering.
505
506         ``local_port`` specifies source TCP port for iBGP peering.
507
508         ``local_as`` specifies local AS number per-peer.
509         If omitted, the AS number of BGPSpeaker instance is used.
510
511         ``connect_mode`` specifies how to connect to this neighbor.
512         This parameter must be one of the following.
513
514         - CONNECT_MODE_ACTIVE         = 'active'
515         - CONNECT_MODE_PASSIVE        = 'passive'
516         - CONNECT_MODE_BOTH (default) = 'both'
517         """
518         bgp_neighbor = {
519             neighbors.IP_ADDRESS: address,
520             neighbors.REMOTE_AS: remote_as,
521             REMOTE_PORT: remote_port,
522             PEER_NEXT_HOP: next_hop,
523             PASSWORD: password,
524             IS_ROUTE_SERVER_CLIENT: is_route_server_client,
525             IS_ROUTE_REFLECTOR_CLIENT: is_route_reflector_client,
526             IS_NEXT_HOP_SELF: is_next_hop_self,
527             CONNECT_MODE: connect_mode,
528             CAP_ENHANCED_REFRESH: enable_enhanced_refresh,
529             CAP_FOUR_OCTET_AS_NUMBER: enable_four_octet_as_number,
530             CAP_MBGP_IPV4: enable_ipv4,
531             CAP_MBGP_IPV6: enable_ipv6,
532             CAP_MBGP_VPNV4: enable_vpnv4,
533             CAP_MBGP_VPNV6: enable_vpnv6,
534             CAP_MBGP_EVPN: enable_evpn,
535             CAP_MBGP_IPV4FS: enable_ipv4fs,
536             CAP_MBGP_IPV6FS: enable_ipv6fs,
537             CAP_MBGP_VPNV4FS: enable_vpnv4fs,
538             CAP_MBGP_VPNV6FS: enable_vpnv6fs,
539             CAP_MBGP_L2VPNFS: enable_l2vpnfs,
540         }
541
542         if multi_exit_disc:
543             bgp_neighbor[MULTI_EXIT_DISC] = multi_exit_disc
544
545         if site_of_origins:
546             bgp_neighbor[SITE_OF_ORIGINS] = site_of_origins
547
548         if local_address:
549             bgp_neighbor[LOCAL_ADDRESS] = local_address
550
551         if local_port:
552             bgp_neighbor[LOCAL_PORT] = local_port
553
554         if local_as:
555             bgp_neighbor[LOCAL_AS] = local_as
556
557         call('neighbor.create', **bgp_neighbor)
558
559     def neighbor_del(self, address):
560         """ This method unregister the registered neighbor. If a session with
561         the peer exists, the session will be closed.
562
563         ``address`` specifies the IP address of the peer. It must be
564         the string representation of an IP address.
565         """
566         bgp_neighbor = {
567             neighbors.IP_ADDRESS: address,
568         }
569
570         call('neighbor.delete', **bgp_neighbor)
571
572     def neighbor_reset(self, address):
573         """ This method reset the registered neighbor.
574
575         ``address`` specifies the IP address of the peer. It must be
576         the string representation of an IP address.
577         """
578         bgp_neighbor = {
579             neighbors.IP_ADDRESS: address,
580         }
581
582         call('core.reset_neighbor', **bgp_neighbor)
583
584     def neighbor_update(self, address, conf_type, conf_value):
585         """ This method changes the neighbor configuration.
586
587         ``address`` specifies the IP address of the peer.
588
589         ``conf_type`` specifies configuration type which you want to change.
590         Currently ryu.services.protocols.bgp.bgpspeaker.MULTI_EXIT_DISC
591         can be specified.
592
593         ``conf_value`` specifies value for the configuration type.
594         """
595
596         assert conf_type == MULTI_EXIT_DISC or conf_type == CONNECT_MODE
597
598         func_name = 'neighbor.update'
599         attribute_param = {}
600         if conf_type == MULTI_EXIT_DISC:
601             attribute_param = {neighbors.MULTI_EXIT_DISC: conf_value}
602         elif conf_type == CONNECT_MODE:
603             attribute_param = {neighbors.CONNECT_MODE: conf_value}
604
605         param = {neighbors.IP_ADDRESS: address,
606                  neighbors.CHANGES: attribute_param}
607
608         call(func_name, **param)
609
610     def neighbor_state_get(self, address=None, format='json'):
611         """ This method returns the state of peer(s) in a json
612         format.
613
614         ``address`` specifies the address of a peer. If not given, the
615         state of all the peers return.
616
617         ``format`` specifies the format of the response.
618         This parameter must be one of the following.
619
620         - 'json' (default)
621         - 'cli'
622         """
623         show = {
624             'params': ['neighbor', 'summary'],
625             'format': format,
626         }
627         if address:
628             show['params'].append(address)
629
630         return call('operator.show', **show)
631
632     def prefix_add(self, prefix, next_hop=None, route_dist=None):
633         """ This method adds a new prefix to be advertised.
634
635         ``prefix`` must be the string representation of an IP network
636         (e.g., 10.1.1.0/24).
637
638         ``next_hop`` specifies the next hop address for this
639         prefix. This parameter is necessary for only VPNv4 and VPNv6
640         address families.
641
642         ``route_dist`` specifies a route distinguisher value. This
643         parameter is necessary for only VPNv4 and VPNv6 address
644         families.
645         """
646         func_name = 'network.add'
647         networks = {
648             PREFIX: prefix,
649         }
650         if next_hop:
651             networks[NEXT_HOP] = next_hop
652         if route_dist:
653             func_name = 'prefix.add_local'
654             networks[ROUTE_DISTINGUISHER] = route_dist
655
656             rf, p = self._check_rf_and_normalize(prefix)
657             networks[ROUTE_FAMILY] = rf
658             networks[PREFIX] = p
659
660             if rf == vrfs.VRF_RF_IPV6 and ip.valid_ipv4(next_hop):
661                 # convert the next_hop to IPv4-Mapped IPv6 Address
662                 networks[NEXT_HOP] = \
663                     str(netaddr.IPAddress(next_hop).ipv6())
664
665         return call(func_name, **networks)
666
667     def prefix_del(self, prefix, route_dist=None):
668         """ This method deletes a advertised prefix.
669
670         ``prefix`` must be the string representation of an IP network.
671
672         ``route_dist`` specifies a route distinguisher value.
673         """
674         func_name = 'network.del'
675         networks = {
676             PREFIX: prefix,
677         }
678         if route_dist:
679             func_name = 'prefix.delete_local'
680             networks[ROUTE_DISTINGUISHER] = route_dist
681
682             rf, p = self._check_rf_and_normalize(prefix)
683             networks[ROUTE_FAMILY] = rf
684             networks[PREFIX] = p
685
686         call(func_name, **networks)
687
688     def evpn_prefix_add(self, route_type, route_dist, esi=0,
689                         ethernet_tag_id=None, mac_addr=None, ip_addr=None,
690                         ip_prefix=None, gw_ip_addr=None, vni=None,
691                         next_hop=None, tunnel_type=None, pmsi_tunnel_type=None,
692                         redundancy_mode=None):
693         """ This method adds a new EVPN route to be advertised.
694
695         ``route_type`` specifies one of the EVPN route type name.
696         This parameter must be one of the following.
697
698         - EVPN_ETH_AUTO_DISCOVERY   = 'eth_ad'
699         - EVPN_MAC_IP_ADV_ROUTE     = 'mac_ip_adv'
700         - EVPN_MULTICAST_ETAG_ROUTE = 'multicast_etag'
701         - EVPN_ETH_SEGMENT          = 'eth_seg'
702         - EVPN_IP_PREFIX_ROUTE      = 'ip_prefix'
703
704         ``route_dist`` specifies a route distinguisher value.
705
706         ``esi`` is an value to specify the Ethernet Segment Identifier.
707         0 is the default and denotes a single-homed site.
708         If you want to advertise esi other than 0,
709         it must be set as dictionary type.
710         If esi is dictionary type, 'type' key must be set
711         and specifies ESI type.
712         For the supported ESI type, see :py:mod:`ryu.lib.packet.bgp.EvpnEsi`.
713         The remaining arguments are the same as that for
714         the corresponding class.
715
716         ``ethernet_tag_id`` specifies the Ethernet Tag ID.
717
718         ``mac_addr`` specifies a MAC address to advertise.
719
720         ``ip_addr`` specifies an IPv4 or IPv6 address to advertise.
721
722         ``ip_prefix`` specifies an IPv4 or IPv6 prefix to advertise.
723
724         ``gw_ip_addr`` specifies an IPv4 or IPv6 address of
725         gateway to advertise.
726
727         ``vni`` specifies an Virtual Network Identifier for VXLAN
728         or Virtual Subnet Identifier for NVGRE.
729         If tunnel_type is not TUNNEL_TYPE_VXLAN or TUNNEL_TYPE_NVGRE,
730         this field is ignored.
731
732         ``next_hop`` specifies the next hop address for this prefix.
733
734         ``tunnel_type`` specifies the data plane encapsulation type
735         to advertise. By the default, this attribute is not advertised.
736         The supported encapsulation types are following.
737
738         - TUNNEL_TYPE_VXLAN = 'vxlan'
739         - TUNNEL_TYPE_NVGRE = 'nvgre
740
741         ``pmsi_tunnel_type`` specifies the type of the PMSI tunnel attribute
742         used to encode the multicast tunnel identifier.
743         This attribute is advertised only if route_type is
744         EVPN_MULTICAST_ETAG_ROUTE and not advertised by the default.
745         This attribute can also carry vni if tunnel_type is specified.
746         The supported PMSI tunnel types are following.
747
748         - PMSI_TYPE_NO_TUNNEL_INFO = 0
749         - PMSI_TYPE_INGRESS_REP    = 6
750
751         ``redundancy_mode`` specifies a redundancy mode type.
752         This attribute is advertised only if route_type is
753         EVPN_ETH_AUTO_DISCOVERY and not advertised by the default.
754         The supported redundancy mode types are following.
755
756         - REDUNDANCY_MODE_ALL_ACTIVE    = 'all_active'
757         - REDUNDANCY_MODE_SINGLE_ACTIVE = 'single_active'
758         """
759         func_name = 'evpn_prefix.add_local'
760
761         # Check the default values
762         if not next_hop:
763             next_hop = '0.0.0.0'
764
765         # Set required arguments
766         kwargs = {EVPN_ROUTE_TYPE: route_type,
767                   ROUTE_DISTINGUISHER: route_dist,
768                   NEXT_HOP: next_hop}
769
770         # Set optional arguments
771         if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
772             kwargs[TUNNEL_TYPE] = tunnel_type
773         elif tunnel_type is not None:
774             raise ValueError('Unsupported tunnel type: %s' % tunnel_type)
775
776         # Set route type specific arguments
777         if route_type == EVPN_ETH_AUTO_DISCOVERY:
778             kwargs.update({
779                 EVPN_ESI: esi,
780                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
781             })
782             if vni is not None:
783                 kwargs[EVPN_VNI] = vni
784             # Set Redundancy Mode Attribute arguments
785             if redundancy_mode in [
786                     REDUNDANCY_MODE_ALL_ACTIVE,
787                     REDUNDANCY_MODE_SINGLE_ACTIVE]:
788                 kwargs[REDUNDANCY_MODE] = redundancy_mode
789             elif redundancy_mode is not None:
790                 raise ValueError('Unsupported Redundancy Mode: %s' %
791                                  redundancy_mode)
792         elif route_type == EVPN_MAC_IP_ADV_ROUTE:
793             kwargs.update({
794                 EVPN_ESI: esi,
795                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
796                 MAC_ADDR: mac_addr,
797                 IP_ADDR: ip_addr,
798             })
799             # Set tunnel type specific arguments
800             if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
801                 kwargs[EVPN_VNI] = vni
802         elif route_type == EVPN_MULTICAST_ETAG_ROUTE:
803             kwargs.update({
804                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
805                 IP_ADDR: ip_addr,
806             })
807             # Set tunnel type specific arguments
808             if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
809                 kwargs[EVPN_VNI] = vni
810             # Set PMSI Tunnel Attribute arguments
811             if pmsi_tunnel_type in [
812                     PMSI_TYPE_NO_TUNNEL_INFO,
813                     PMSI_TYPE_INGRESS_REP]:
814                 kwargs[PMSI_TUNNEL_TYPE] = pmsi_tunnel_type
815             elif pmsi_tunnel_type is not None:
816                 raise ValueError('Unsupported PMSI tunnel type: %s' %
817                                  pmsi_tunnel_type)
818         elif route_type == EVPN_ETH_SEGMENT:
819             kwargs.update({
820                 EVPN_ESI: esi,
821                 IP_ADDR: ip_addr,
822             })
823         elif route_type == EVPN_IP_PREFIX_ROUTE:
824             kwargs.update({
825                 EVPN_ESI: esi,
826                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
827                 IP_PREFIX: ip_prefix,
828                 GW_IP_ADDR: gw_ip_addr,
829             })
830             # Set tunnel type specific arguments
831             if tunnel_type in [TUNNEL_TYPE_VXLAN, TUNNEL_TYPE_NVGRE]:
832                 kwargs[EVPN_VNI] = vni
833         else:
834             raise ValueError('Unsupported EVPN route type: %s' % route_type)
835
836         call(func_name, **kwargs)
837
838     def evpn_prefix_del(self, route_type, route_dist, esi=0,
839                         ethernet_tag_id=None, mac_addr=None, ip_addr=None,
840                         ip_prefix=None):
841         """ This method deletes an advertised EVPN route.
842
843         ``route_type`` specifies one of the EVPN route type name.
844
845         ``route_dist`` specifies a route distinguisher value.
846
847         ``esi`` is an value to specify the Ethernet Segment Identifier.
848
849         ``ethernet_tag_id`` specifies the Ethernet Tag ID.
850
851         ``mac_addr`` specifies a MAC address to advertise.
852
853         ``ip_addr`` specifies an IPv4 or IPv6 address to advertise.
854
855         ``ip_prefix`` specifies an IPv4 or IPv6 prefix to advertise.
856         """
857         func_name = 'evpn_prefix.delete_local'
858
859         # Set required arguments
860         kwargs = {EVPN_ROUTE_TYPE: route_type,
861                   ROUTE_DISTINGUISHER: route_dist}
862
863         # Set route type specific arguments
864         if route_type == EVPN_ETH_AUTO_DISCOVERY:
865             kwargs.update({
866                 EVPN_ESI: esi,
867                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
868             })
869         elif route_type == EVPN_MAC_IP_ADV_ROUTE:
870             kwargs.update({
871                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
872                 MAC_ADDR: mac_addr,
873                 IP_ADDR: ip_addr,
874             })
875         elif route_type == EVPN_MULTICAST_ETAG_ROUTE:
876             kwargs.update({
877                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
878                 IP_ADDR: ip_addr,
879             })
880         elif route_type == EVPN_ETH_SEGMENT:
881             kwargs.update({
882                 EVPN_ESI: esi,
883                 IP_ADDR: ip_addr,
884             })
885         elif route_type == EVPN_IP_PREFIX_ROUTE:
886             kwargs.update({
887                 EVPN_ETHERNET_TAG_ID: ethernet_tag_id,
888                 IP_PREFIX: ip_prefix,
889             })
890         else:
891             raise ValueError('Unsupported EVPN route type: %s' % route_type)
892
893         call(func_name, **kwargs)
894
895     def flowspec_prefix_add(self, flowspec_family, rules, route_dist=None,
896                             actions=None):
897         """ This method adds a new Flow Specification prefix to be advertised.
898
899         ``flowspec_family`` specifies one of the flowspec family name.
900         This parameter must be one of the following.
901
902         - FLOWSPEC_FAMILY_IPV4  = 'ipv4fs'
903         - FLOWSPEC_FAMILY_IPV6  = 'ipv6fs'
904         - FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
905         - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
906         - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs'
907
908         ``rules`` specifies NLRIs of Flow Specification as
909         a dictionary type value.
910         For the supported NLRI types and arguments,
911         see `from_user()` method of the following classes.
912
913         - :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv4NLRI`
914         - :py:mod:`ryu.lib.packet.bgp.FlowSpecIPv6NLRI`
915         - :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv4NLRI`
916         - :py:mod:`ryu.lib.packet.bgp.FlowSpecVPNv6NLRI`
917         - :py:mod:`ryu.lib.packet.bgp.FlowSpecL2VPNNLRI`
918
919         ``route_dist`` specifies a route distinguisher value.
920         This parameter is required only if flowspec_family is one of the
921         following address family.
922
923         - FLOWSPEC_FAMILY_VPNV4 = 'vpnv4fs'
924         - FLOWSPEC_FAMILY_VPNV6 = 'vpnv6fs'
925         - FLOWSPEC_FAMILY_L2VPN = 'l2vpnfs'
926
927         ``actions`` specifies Traffic Filtering Actions of
928         Flow Specification as a dictionary type value.
929         The keys are "ACTION_NAME" for each action class and
930         values are used for the arguments to that class.
931         For the supported "ACTION_NAME" and arguments,
932         see the following table.
933
934         =============== ===============================================================
935         ACTION_NAME     Action Class
936         =============== ===============================================================
937         traffic_rate    :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficRateCommunity`
938         traffic_action  :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficActionCommunity`
939         redirect        :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecRedirectCommunity`
940         traffic_marking :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTrafficMarkingCommunity`
941         vlan_action     :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecVlanActionCommunity`
942         tpid_action     :py:mod:`ryu.lib.packet.bgp.BGPFlowSpecTPIDActionCommunity`
943         =============== ===============================================================
944
945         Example(IPv4)::
946
947             >>> speaker = BGPSpeaker(as_number=65001, router_id='172.17.0.1')
948             >>> speaker.neighbor_add(address='172.17.0.2',
949             ...                      remote_as=65002,
950             ...                      enable_ipv4fs=True)
951             >>> speaker.flowspec_prefix_add(
952             ...     flowspec_family=FLOWSPEC_FAMILY_IPV4,
953             ...     rules={
954             ...         'dst_prefix': '10.60.1.0/24'
955             ...     },
956             ...     actions={
957             ...         'traffic_marking': {
958             ...             'dscp': 24
959             ...         }
960             ...     }
961             ... )
962
963         Example(VPNv4)::
964
965             >>> speaker = BGPSpeaker(as_number=65001, router_id='172.17.0.1')
966             >>> speaker.neighbor_add(address='172.17.0.2',
967             ...                      remote_as=65002,
968             ...                      enable_vpnv4fs=True)
969             >>> speaker.vrf_add(route_dist='65001:100',
970             ...                 import_rts=['65001:100'],
971             ...                 export_rts=['65001:100'],
972             ...                 route_family=RF_VPNV4_FLOWSPEC)
973             >>> speaker.flowspec_prefix_add(
974             ...     flowspec_family=FLOWSPEC_FAMILY_VPNV4,
975             ...     route_dist='65000:100',
976             ...     rules={
977             ...         'dst_prefix': '10.60.1.0/24'
978             ...     },
979             ...     actions={
980             ...         'traffic_marking': {
981             ...             'dscp': 24
982             ...         }
983             ...     }
984             ... )
985         """
986         func_name = 'flowspec.add'
987
988         # Set required arguments
989         kwargs = {
990             FLOWSPEC_FAMILY: flowspec_family,
991             FLOWSPEC_RULES: rules,
992             FLOWSPEC_ACTIONS: actions or {},
993         }
994
995         if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6,
996                                FLOWSPEC_FAMILY_L2VPN]:
997             func_name = 'flowspec.add_local'
998             kwargs.update({ROUTE_DISTINGUISHER: route_dist})
999
1000         call(func_name, **kwargs)
1001
1002     def flowspec_prefix_del(self, flowspec_family, rules, route_dist=None):
1003         """ This method deletes an advertised Flow Specification route.
1004
1005         ``flowspec_family`` specifies one of the flowspec family name.
1006
1007         ``rules`` specifies NLRIs of Flow Specification as
1008         a dictionary type value.
1009
1010         ``route_dist`` specifies a route distinguisher value.
1011         """
1012         func_name = 'flowspec.del'
1013
1014         # Set required arguments
1015         kwargs = {
1016             FLOWSPEC_FAMILY: flowspec_family,
1017             FLOWSPEC_RULES: rules,
1018         }
1019
1020         if flowspec_family in [FLOWSPEC_FAMILY_VPNV4, FLOWSPEC_FAMILY_VPNV6,
1021                                FLOWSPEC_FAMILY_L2VPN]:
1022             func_name = 'flowspec.del_local'
1023             kwargs.update({ROUTE_DISTINGUISHER: route_dist})
1024
1025         call(func_name, **kwargs)
1026
1027     def vrf_add(self, route_dist, import_rts, export_rts, site_of_origins=None,
1028                 route_family=RF_VPN_V4, multi_exit_disc=None):
1029         """ This method adds a new vrf used for VPN.
1030
1031         ``route_dist`` specifies a route distinguisher value.
1032
1033         ``import_rts`` specifies a list of route targets to be imported.
1034
1035         ``export_rts`` specifies a list of route targets to be exported.
1036
1037         ``site_of_origins`` specifies site_of_origin values.
1038         This parameter must be a list of string.
1039
1040         ``route_family`` specifies route family of the VRF.
1041         This parameter must be one of the following.
1042
1043         - RF_VPN_V4 (default) = 'ipv4'
1044         - RF_VPN_V6           = 'ipv6'
1045         - RF_L2_EVPN          = 'evpn'
1046         - RF_VPNV4_FLOWSPEC   = 'ipv4fs'
1047         - RF_VPNV6_FLOWSPEC   = 'ipv6fs'
1048         - RF_L2VPN_FLOWSPEC   = 'l2vpnfs'
1049
1050         ``multi_exit_disc`` specifies multi exit discriminator (MED) value.
1051         It must be an integer.
1052         """
1053         if route_family not in SUPPORTED_VRF_RF:
1054             raise ValueError('Unsupported route_family: %s' % route_family)
1055
1056         vrf = {
1057             vrfs.ROUTE_DISTINGUISHER: route_dist,
1058             vrfs.IMPORT_RTS: import_rts,
1059             vrfs.EXPORT_RTS: export_rts,
1060             vrfs.SITE_OF_ORIGINS: site_of_origins,
1061             vrfs.VRF_RF: route_family,
1062             vrfs.MULTI_EXIT_DISC: multi_exit_disc,
1063         }
1064
1065         call('vrf.create', **vrf)
1066
1067     def vrf_del(self, route_dist):
1068         """ This method deletes the existing vrf.
1069
1070         ``route_dist`` specifies a route distinguisher value.
1071         """
1072
1073         vrf = {vrfs.ROUTE_DISTINGUISHER: route_dist}
1074
1075         call('vrf.delete', **vrf)
1076
1077     def vrfs_get(self, subcommand='routes', route_dist=None,
1078                  route_family='all', format='json'):
1079         """ This method returns the existing vrfs.
1080
1081         ``subcommand`` specifies one of the following.
1082
1083         - 'routes': shows routes present for vrf
1084         - 'summary': shows configuration and summary of vrf
1085
1086         ``route_dist`` specifies a route distinguisher value.
1087         If route_family is not 'all', this value must be specified.
1088
1089         ``route_family`` specifies route family of the VRF.
1090         This parameter must be one of the following.
1091
1092         - RF_VPN_V4  = 'ipv4'
1093         - RF_VPN_V6  = 'ipv6'
1094         - RF_L2_EVPN = 'evpn'
1095         - 'all' (default)
1096
1097         ``format`` specifies the format of the response.
1098         This parameter must be one of the following.
1099
1100         - 'json' (default)
1101         - 'cli'
1102         """
1103         show = {
1104             'format': format,
1105         }
1106         if route_family in SUPPORTED_VRF_RF:
1107             assert route_dist is not None
1108             show['params'] = ['vrf', subcommand, route_dist, route_family]
1109         else:
1110             show['params'] = ['vrf', subcommand, 'all']
1111
1112         return call('operator.show', **show)
1113
1114     def rib_get(self, family='all', format='json'):
1115         """ This method returns the BGP routing information in a json
1116         format. This will be improved soon.
1117
1118         ``family`` specifies the address family of the RIB (e.g. 'ipv4').
1119
1120         ``format`` specifies the format of the response.
1121         This parameter must be one of the following.
1122
1123         - 'json' (default)
1124         - 'cli'
1125         """
1126         show = {
1127             'params': ['rib', family],
1128             'format': format
1129         }
1130
1131         return call('operator.show', **show)
1132
1133     def neighbor_get(self, route_type, address, format='json'):
1134         """ This method returns the BGP adj-RIB-in/adj-RIB-out information
1135         in a json format.
1136
1137         ``route_type`` This parameter is necessary for only received-routes
1138         and sent-routes.
1139
1140         - received-routes : paths received and not withdrawn by given peer
1141         - sent-routes : paths sent and not withdrawn to given peer
1142
1143         ``address`` specifies the IP address of the peer. It must be
1144         the string representation of an IP address.
1145
1146         ``format`` specifies the format of the response.
1147         This parameter must be one of the following.
1148
1149         - 'json' (default)
1150         - 'cli'
1151         """
1152         show = {
1153             'format': format,
1154         }
1155         if route_type == 'sent-routes' or route_type == 'received-routes':
1156             show['params'] = ['neighbor', route_type, address, 'all']
1157         else:
1158             show['params'] = ['neighbor', 'received-routes', address, 'all']
1159
1160         return call('operator.show', **show)
1161
1162     def neighbors_get(self, format='json'):
1163         """ This method returns a list of the BGP neighbors.
1164
1165         ``format`` specifies the format of the response.
1166         This parameter must be one of the following.
1167
1168         - 'json' (default)
1169         - 'cli'
1170         """
1171         show = {
1172             'params': ['neighbor'],
1173             'format': format,
1174         }
1175
1176         return call('operator.show', **show)
1177
1178     def _set_filter(self, filter_type, address, filters):
1179         assert filter_type in ('in', 'out'), (
1180             "filter type must be 'in' or 'out'")
1181
1182         assert all(isinstance(f, Filter) for f in filters), (
1183             'all the items in filters must be an instance of Filter sub-class')
1184
1185         if filters is None:
1186             filters = []
1187
1188         func_name = 'neighbor.' + filter_type + '_filter.set'
1189         param = {
1190             neighbors.IP_ADDRESS: address,
1191         }
1192         if filter_type == 'in':
1193             param[neighbors.IN_FILTER] = filters
1194         else:
1195             param[neighbors.OUT_FILTER] = filters
1196
1197         call(func_name, **param)
1198
1199     def out_filter_set(self, address, filters):
1200         """ This method sets out-filter to neighbor.
1201
1202         ``address`` specifies the IP address of the peer.
1203
1204         ``filters`` specifies a filter list to filter the path advertisement.
1205         The contents must be an instance of Filter sub-class
1206
1207         If you want to define out-filter that send only a particular
1208         prefix to neighbor, filters can be created as follows::
1209
1210             p = PrefixFilter('10.5.111.0/24',
1211                              policy=PrefixFilter.POLICY_PERMIT)
1212
1213             all = PrefixFilter('0.0.0.0/0',
1214                                policy=PrefixFilter.POLICY_DENY)
1215
1216             pList = [p, all]
1217
1218             self.bgpspeaker.out_filter_set(neighbor_address, pList)
1219
1220         .. Note::
1221
1222             out-filter evaluates paths in the order of Filter in the pList.
1223         """
1224
1225         self._set_filter('out', address, filters)
1226
1227     def out_filter_get(self, address):
1228         """ This method gets out-filter setting from the specified neighbor.
1229
1230         ``address`` specifies the IP address of the peer.
1231
1232         Returns a list object containing an instance of Filter sub-class
1233         """
1234
1235         func_name = 'neighbor.out_filter.get'
1236         param = {
1237             neighbors.IP_ADDRESS: address,
1238         }
1239
1240         return call(func_name, **param)
1241
1242     def in_filter_set(self, address, filters):
1243         """This method sets in-bound filters to a neighbor.
1244
1245         ``address`` specifies the IP address of the neighbor
1246
1247         ``filters`` specifies filter list applied before advertised paths are
1248         imported to the global rib. All the items in the list must be an
1249         instance of Filter sub-class.
1250         """
1251
1252         self._set_filter('in', address, filters)
1253
1254     def in_filter_get(self, address):
1255         """This method gets in-bound filters of the specified neighbor.
1256
1257         ``address`` specifies the IP address of the neighbor.
1258
1259         Returns a list object containing an instance of Filter sub-class
1260         """
1261
1262         func_name = 'neighbor.in_filter.get'
1263         param = {
1264             neighbors.IP_ADDRESS: address,
1265         }
1266
1267         return call(func_name, **param)
1268
1269     def bmp_server_add(self, address, port):
1270         """This method registers a new BMP (BGP monitoring Protocol)
1271         server. The BGP speaker starts to send BMP messages to the
1272         server. Currently, only one BMP server can be registered.
1273
1274         ``address`` specifies the IP address of a BMP server.
1275
1276         ``port`` specifies the listen port number of a BMP server.
1277         """
1278
1279         func_name = 'bmp.start'
1280         param = {
1281             'host': address,
1282             'port': port,
1283         }
1284
1285         call(func_name, **param)
1286
1287     def bmp_server_del(self, address, port):
1288         """ This method unregister the registered BMP server.
1289
1290         ``address`` specifies the IP address of a BMP server.
1291
1292         ``port`` specifies the listen port number of a BMP server.
1293         """
1294
1295         func_name = 'bmp.stop'
1296         param = {
1297             'host': address,
1298             'port': port,
1299         }
1300
1301         call(func_name, **param)
1302
1303     def attribute_map_set(self, address, attribute_maps,
1304                           route_dist=None, route_family=RF_VPN_V4):
1305         """This method sets attribute mapping to a neighbor.
1306         attribute mapping can be used when you want to apply
1307         attribute to BGPUpdate under specific conditions.
1308
1309         ``address`` specifies the IP address of the neighbor
1310
1311         ``attribute_maps`` specifies attribute_map list that are used
1312         before paths are advertised. All the items in the list must
1313         be an instance of AttributeMap class
1314
1315         ``route_dist`` specifies route dist in which attribute_maps
1316         are added.
1317
1318         ``route_family`` specifies route family of the VRF.
1319         This parameter must be one of the following.
1320
1321         - RF_VPN_V4 (default) = 'ipv4'
1322         - RF_VPN_V6           = 'ipv6'
1323
1324         We can set AttributeMap to a neighbor as follows::
1325
1326             pref_filter = PrefixFilter('192.168.103.0/30',
1327                                        PrefixFilter.POLICY_PERMIT)
1328
1329             attribute_map = AttributeMap([pref_filter],
1330                                          AttributeMap.ATTR_LOCAL_PREF, 250)
1331
1332             speaker.attribute_map_set('192.168.50.102', [attribute_map])
1333         """
1334
1335         if route_family not in SUPPORTED_VRF_RF:
1336             raise ValueError('Unsupported route_family: %s' % route_family)
1337
1338         func_name = 'neighbor.attribute_map.set'
1339         param = {
1340             neighbors.IP_ADDRESS: address,
1341             neighbors.ATTRIBUTE_MAP: attribute_maps,
1342         }
1343         if route_dist is not None:
1344             param[vrfs.ROUTE_DISTINGUISHER] = route_dist
1345             param[vrfs.VRF_RF] = route_family
1346
1347         call(func_name, **param)
1348
1349     def attribute_map_get(self, address, route_dist=None,
1350                           route_family=RF_VPN_V4):
1351         """This method gets in-bound filters of the specified neighbor.
1352
1353         ``address`` specifies the IP address of the neighbor.
1354
1355         ``route_dist`` specifies route distinguisher that has attribute_maps.
1356
1357         ``route_family`` specifies route family of the VRF.
1358         This parameter must be one of the following.
1359
1360         - RF_VPN_V4 (default) = 'ipv4'
1361         - RF_VPN_V6           = 'ipv6'
1362
1363         Returns a list object containing an instance of AttributeMap
1364         """
1365
1366         if route_family not in SUPPORTED_VRF_RF:
1367             raise ValueError('Unsupported route_family: %s' % route_family)
1368
1369         func_name = 'neighbor.attribute_map.get'
1370         param = {
1371             neighbors.IP_ADDRESS: address,
1372         }
1373         if route_dist is not None:
1374             param[vrfs.ROUTE_DISTINGUISHER] = route_dist
1375             param[vrfs.VRF_RF] = route_family
1376
1377         return call(func_name, **param)
1378
1379     @staticmethod
1380     def _check_rf_and_normalize(prefix):
1381         """ check prefix's route_family and if the address is
1382         IPv6 address, return IPv6 route_family and normalized IPv6 address.
1383         If the address is IPv4 address, return IPv4 route_family
1384         and the prefix itself.
1385         """
1386         addr, masklen = prefix.split('/')
1387         if ip.valid_ipv6(addr):
1388             # normalize IPv6 address
1389             ipv6_prefix = str(netaddr.IPAddress(addr)) + '/' + masklen
1390             return vrfs.VRF_RF_IPV6, ipv6_prefix
1391         else:
1392             return vrfs.VRF_RF_IPV4, prefix