mirror of
https://github.com/faucetsdn/ryu.git
synced 2026-01-25 10:32:03 +01:00
BGPSpeaker: Support to advertise Tunnel Encapsulation
This patch adds support to advertise the BGP Tunnel Encapsulation Attribute for the Ethernet VPN Routes. Signed-off-by: IWASE Yusuke <iwase.yusuke0@gmail.com> Signed-off-by: FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp>
This commit is contained in:
parent
bd4e8a70b5
commit
40fe7ffdc5
@ -2795,6 +2795,26 @@ class BGPEncapsulationExtendedCommunity(_ExtendedCommunity):
|
||||
super(BGPEncapsulationExtendedCommunity, self).__init__()
|
||||
self.do_init(BGPEncapsulationExtendedCommunity, self, kwargs)
|
||||
|
||||
@classmethod
|
||||
def from_str(cls, tunnel_type):
|
||||
"""
|
||||
Returns an instance identified with the given `tunnel_type`.
|
||||
|
||||
`tunnel_type` should be a str type value and corresponding to
|
||||
BGP Tunnel Encapsulation Attribute Tunnel Type constants name
|
||||
omitting `TUNNEL_TYPE_` prefix.
|
||||
|
||||
Example:
|
||||
- `gre` means TUNNEL_TYPE_GRE
|
||||
- `vxlan` means TUNNEL_TYPE_VXLAN
|
||||
|
||||
And raises AttributeError when the corresponding Tunnel Type
|
||||
is not found to the given `tunnel_type`.
|
||||
"""
|
||||
return cls(subtype=_ExtendedCommunity.SUBTYPE_ENCAPSULATION,
|
||||
tunnel_type=getattr(cls,
|
||||
'TUNNEL_TYPE_' + tunnel_type.upper()))
|
||||
|
||||
|
||||
@_ExtendedCommunity.register_type(_ExtendedCommunity.EVPN_MAC_MOBILITY)
|
||||
class BGPEvpnMacMobilityExtendedCommunity(_ExtendedCommunity):
|
||||
|
||||
@ -49,6 +49,7 @@ EVPN_ETHERNET_TAG_ID = 'ethernet_tag_id'
|
||||
MAC_ADDR = 'mac_addr'
|
||||
IP_ADDR = 'ip_addr'
|
||||
MPLS_LABELS = 'mpls_labels'
|
||||
TUNNEL_TYPE = 'tunnel_type'
|
||||
|
||||
# API call registry
|
||||
_CALL_REGISTRY = {}
|
||||
|
||||
@ -31,6 +31,7 @@ from ryu.services.protocols.bgp.api.base import PREFIX
|
||||
from ryu.services.protocols.bgp.api.base import RegisterWithArgChecks
|
||||
from ryu.services.protocols.bgp.api.base import ROUTE_DISTINGUISHER
|
||||
from ryu.services.protocols.bgp.api.base import VPN_LABEL
|
||||
from ryu.services.protocols.bgp.api.base import TUNNEL_TYPE
|
||||
from ryu.services.protocols.bgp.base import add_bgp_error_metadata
|
||||
from ryu.services.protocols.bgp.base import PREFIX_ERROR_CODE
|
||||
from ryu.services.protocols.bgp.base import validate
|
||||
@ -54,6 +55,20 @@ SUPPORTED_EVPN_ROUTE_TYPES = [
|
||||
EVPN_MULTICAST_ETAG_ROUTE,
|
||||
]
|
||||
|
||||
# Constants for BGP Tunnel Encapsulation Attribute
|
||||
TUNNEL_TYPE_VXLAN = 'vxlan'
|
||||
TUNNEL_TYPE_NVGRE = 'nvgre'
|
||||
TUNNEL_TYPE_MPLS = 'mpls'
|
||||
TUNNEL_TYPE_MPLS_IN_GRE = 'mpls_in_gre'
|
||||
TUNNEL_TYPE_VXLAN_GRE = 'vxlan_gre'
|
||||
SUPPORTED_TUNNEL_TYPES = [
|
||||
TUNNEL_TYPE_VXLAN,
|
||||
TUNNEL_TYPE_NVGRE,
|
||||
TUNNEL_TYPE_MPLS,
|
||||
TUNNEL_TYPE_MPLS_IN_GRE,
|
||||
TUNNEL_TYPE_VXLAN_GRE,
|
||||
]
|
||||
|
||||
|
||||
@add_bgp_error_metadata(code=PREFIX_ERROR_CODE,
|
||||
sub_code=1,
|
||||
@ -122,6 +137,13 @@ def is_valid_mpls_labels(labels):
|
||||
conf_value=labels)
|
||||
|
||||
|
||||
@validate(name=TUNNEL_TYPE)
|
||||
def is_valid_tunnel_type(tunnel_type):
|
||||
if tunnel_type not in SUPPORTED_TUNNEL_TYPES:
|
||||
raise ConfigValueError(conf_name=TUNNEL_TYPE,
|
||||
conf_value=tunnel_type)
|
||||
|
||||
|
||||
@RegisterWithArgChecks(name='prefix.add_local',
|
||||
req_args=[ROUTE_DISTINGUISHER, PREFIX, NEXT_HOP],
|
||||
opt_args=[VRF_RF])
|
||||
@ -171,7 +193,7 @@ def delete_local(route_dist, prefix, route_family=VRF_RF_IPV4):
|
||||
req_args=[EVPN_ROUTE_TYPE, ROUTE_DISTINGUISHER,
|
||||
NEXT_HOP],
|
||||
opt_args=[EVPN_ESI, EVPN_ETHERNET_TAG_ID, MAC_ADDR,
|
||||
IP_ADDR])
|
||||
IP_ADDR, TUNNEL_TYPE])
|
||||
def add_evpn_local(route_type, route_dist, next_hop, **kwargs):
|
||||
"""Adds EVPN route from VRF identified by *route_dist*.
|
||||
"""
|
||||
|
||||
@ -31,8 +31,10 @@ 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 ROUTE_DISTINGUISHER
|
||||
from ryu.services.protocols.bgp.api.base import ROUTE_FAMILY
|
||||
from ryu.services.protocols.bgp.api.base import TUNNEL_TYPE
|
||||
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 TUNNEL_TYPE_MPLS
|
||||
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 BGP_SERVER_PORT
|
||||
@ -490,7 +492,7 @@ class BGPSpeaker(object):
|
||||
|
||||
def evpn_prefix_add(self, route_type, route_dist, esi=0,
|
||||
ethernet_tag_id=None, mac_addr=None, ip_addr=None,
|
||||
next_hop=None):
|
||||
next_hop=None, tunnel_type=TUNNEL_TYPE_MPLS):
|
||||
""" This method adds a new EVPN route to be advertised.
|
||||
|
||||
``route_type`` specifies one of the EVPN route type name. The
|
||||
@ -509,6 +511,9 @@ class BGPSpeaker(object):
|
||||
``ip_addr`` specifies an IPv4 or IPv6 address to advertise.
|
||||
|
||||
``next_hop`` specifies the next hop address for this prefix.
|
||||
|
||||
``tunnel_type`` specifies the data plane encapsulation type
|
||||
to advertise. The default is the MPLS encapsulation type.
|
||||
"""
|
||||
func_name = 'evpn_prefix.add_local'
|
||||
|
||||
@ -521,6 +526,10 @@ class BGPSpeaker(object):
|
||||
ROUTE_DISTINGUISHER: route_dist,
|
||||
NEXT_HOP: next_hop}
|
||||
|
||||
# Set optional arguments
|
||||
if tunnel_type:
|
||||
kwargs[TUNNEL_TYPE] = tunnel_type
|
||||
|
||||
# Set route type specific arguments
|
||||
if route_type == EVPN_MAC_IP_ADV_ROUTE:
|
||||
kwargs.update({
|
||||
|
||||
@ -482,7 +482,7 @@ class TableCoreManager(object):
|
||||
LOG.debug('No VRF table found that imports RTs: %s', path_rts)
|
||||
|
||||
def update_vrf_table(self, route_dist, prefix=None, next_hop=None,
|
||||
route_family=None, route_type=None,
|
||||
route_family=None, route_type=None, tunnel_type=None,
|
||||
is_withdraw=False, **kwargs):
|
||||
"""Update a BGP route in the VRF table identified by `route_dist`
|
||||
with the given `next_hop`.
|
||||
@ -547,7 +547,7 @@ class TableCoreManager(object):
|
||||
# withdrawal. Hence multiple withdrawals have not side effect.
|
||||
return vrf_table.insert_vrf_path(
|
||||
nlri=prefix, next_hop=next_hop, gen_lbl=gen_lbl,
|
||||
is_withdraw=is_withdraw)
|
||||
is_withdraw=is_withdraw, tunnel_type=tunnel_type)
|
||||
|
||||
def update_global_table(self, prefix, next_hop=None, is_withdraw=False):
|
||||
"""Update a BGP route in the Global table for the given `prefix`
|
||||
|
||||
@ -30,6 +30,7 @@ from ryu.lib.packet.bgp import BGPPathAttributeAsPath
|
||||
from ryu.lib.packet.bgp import BGPPathAttributeExtendedCommunities
|
||||
from ryu.lib.packet.bgp import BGPTwoOctetAsSpecificExtendedCommunity
|
||||
from ryu.lib.packet.bgp import BGPPathAttributeMultiExitDisc
|
||||
from ryu.lib.packet.bgp import BGPEncapsulationExtendedCommunity
|
||||
from ryu.lib.packet.bgp import RF_L2_EVPN
|
||||
from ryu.lib.packet.bgp import EvpnMacIPAdvertisementNLRI
|
||||
|
||||
@ -211,7 +212,7 @@ class VrfTable(Table):
|
||||
return changed_dests
|
||||
|
||||
def insert_vrf_path(self, nlri, next_hop=None,
|
||||
gen_lbl=False, is_withdraw=False):
|
||||
gen_lbl=False, is_withdraw=False, **kwargs):
|
||||
assert nlri
|
||||
pattrs = None
|
||||
label_list = []
|
||||
@ -243,6 +244,12 @@ class VrfTable(Table):
|
||||
local_administrator=int(local_admin),
|
||||
subtype=subtype))
|
||||
|
||||
# Set Tunnel Encapsulation Attribute
|
||||
tunnel_type = kwargs.get('tunnel_type', None)
|
||||
if tunnel_type:
|
||||
communities.append(
|
||||
BGPEncapsulationExtendedCommunity.from_str(tunnel_type))
|
||||
|
||||
pattrs[BGP_ATTR_TYPE_EXTENDED_COMMUNITIES] = \
|
||||
BGPPathAttributeExtendedCommunities(communities=communities)
|
||||
if vrf_conf.multi_exit_disc:
|
||||
@ -266,7 +273,7 @@ class VrfTable(Table):
|
||||
label_list.append(table_manager.get_next_vpnv4_label())
|
||||
|
||||
# Set MPLS labels with the generated labels
|
||||
if isinstance(nlri, EvpnMacIPAdvertisementNLRI):
|
||||
if gen_lbl and isinstance(nlri, EvpnMacIPAdvertisementNLRI):
|
||||
nlri.mpls_labels = label_list[:2]
|
||||
|
||||
puid = self.VRF_PATH_CLASS.create_puid(
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user