original_docstring: Exports the external gateway into the tenant VRF.
  
          The gateway network has to be exported into the tenant VRF for
          it to communicate with the outside world. Also a default route
          has to be set to the external gateway IP address.
          If source_vrf (i.e tenant VRF) is provided,
             - Export the external gateway's IP from VRF=0 into this VRF.
             - Add a default route to the external_gateway in this VRF
          Else,
             - Export the external gateway into into all tenant VRFs
             - Add a default route to the external_gateway in all tenant VRFs
          If the external gateway IP address is not provided:
          All external networks are exported into tenant VRFs
  
          
docstring: Exports the external gateway into the tenant VRF.
  The gateway network has to be exported into the tenant VRF for
  it to communicate with the outside world. Also a default route
  has to be set to the external gateway IP address.
  If source_vrf  is provided,
  Export the external gateway's IP from VRF=0 into this VRF.
  Add a default route to the external_gateway in this VRF
  Else,
  Export the external gateway into into all tenant VRFs
  Add a default route to the external_gateway in all tenant VRFs
  If the external gateway IP address is not provided:
  All external networks are exported into tenant VRFs
docstring_tokens: Exports the external gateway into the tenant VRF . The gateway network has to be exported into the tenant VRF for it to communicate with the outside world . Also a default route has to be set to the external gateway IP address . If source_vrf is provided Export the external gateway ' s IP from VRF = 0 into this VRF . Add a default route to the external_gateway in this VRF Else Export the external gateway into into all tenant VRFs Add a default route to the external_gateway in all tenant VRFs If the external gateway IP address is not provided : All external networks are exported into tenant VRFs
code: def export_routes_from_tenant_vrfs(self, source_vrf=0, is_add=True,
                                         ext_gw_ip=None):
          """Exports the external gateway into the tenant VRF.
  
          The gateway network has to be exported into the tenant VRF for
          it to communicate with the outside world. Also a default route
          has to be set to the external gateway IP address.
          If source_vrf (i.e tenant VRF) is provided,
             - Export the external gateway's IP from VRF=0 into this VRF.
             - Add a default route to the external_gateway in this VRF
          Else,
             - Export the external gateway into into all tenant VRFs
             - Add a default route to the external_gateway in all tenant VRFs
          If the external gateway IP address is not provided:
          All external networks are exported into tenant VRFs
  
          """
          if source_vrf:
              LOG.debug("Router:Exporting external route into tenant VRF:%s",
                        source_vrf)
          else:
              LOG.debug("Router:Exporting external route into all tenant VRFs")
          # TODO(najoy): Check if the tenant ID matches for the gateway router
          # external interface and export only matching external routes.
          for ext_port in self.router_external_interfaces:
              gw_port = self.router_external_interfaces[ext_port]
              for int_port in self.router_interfaces.values():
                  int_vrf = int_port['vrf_id']
                  ext_vrf = gw_port['vrf_id']
                  # If a source vrf is present only update if the VRF matches
                  if source_vrf and int_vrf != source_vrf:
                      continue
                  is_ipv6 = int_port['is_ipv6']
                  default_gw_ip = "::" if is_ipv6 else '0.0.0.0'
                  external_gateway_ip = gw_port['external_gateway_ip']
                  if ext_gw_ip and external_gateway_ip != ext_gw_ip:
                      continue
                  # Get the external and internal networks in the CIDR form
                  ext_network = self._get_ip_network(
                      gw_port['gateway_ip'],
                      gw_port['prefixlen']
                      )
                  int_network = self._get_ip_network(
                      int_port['gateway_ip'],
                      int_port['prefixlen']
                      )
                  if is_add:
                      # Add the default route (0.0.0.0/0) to the
                      # external gateway IP addr, which is outside of VPP
                      # with the next hop sw_if_index set to the external
                      # loopback BVI address.
                      # Note: The external loopback sw_if_index and the
                      # next_hop_address is mandatory here to prevent a VPP
                      # crash - Similar to the CLI command
                      # ip route add table <int-vrf> 0.0.0.0/0 via <next-hop-ip>
                      #                                    <next-hop-sw-indx>
                      #
                      # Note(onong): Do not set IPv6 default gateway to an IPv4
                      # external gateway
                      ext_ip = ip_address(external_gateway_ip)
                      if is_ipv6 and ext_ip.version != 6:
                          LOG.info('Not setting IPv6 default route via an IPv4'
                                   ' external gateway')
                      else:
                          self.vpp.add_ip_route(
                              vrf=int_vrf,
                              ip_address=self._pack_address(default_gw_ip),
                              prefixlen=0,
                              next_hop_address=self._pack_address(
                                  external_gateway_ip),
                              next_hop_sw_if_index=gw_port['bvi_if_idx'],
                              is_ipv6=is_ipv6)
                      # Export the external gateway subnet into the tenant VRF
                      # to enable tenant traffic to flow out. Exporting is done
                      # by setting the next hop sw if index to the loopback's
                      # sw_index (i.e. BVI) on the external network
                      # CLI: ip route add table <int_vrf> <external-subnet>
                      #                                 via <next-hop-sw-indx>
                      #
                      # Note(onong): Do not export an IPv4 external network
                      # into an IPv6 VRF.
                      ext_net = ip_network(ext_network)
                      if is_ipv6 and ext_net.version != 6:
                          LOG.info('Not exporting IPv4 external network into '
                                   'tenant\'s IPv6 VRF')
                      else:
                          self.vpp.add_ip_route(
                              vrf=int_vrf,
                              ip_address=self._pack_address(ext_network),
                              prefixlen=gw_port['prefixlen'],
                              next_hop_address=None,
                              next_hop_sw_if_index=gw_port['bvi_if_idx'],
                              is_ipv6=is_ipv6)
                      # Export the tenant network into external VRF so the
                      # gateway can route return traffic to the tenant VM from
                      # the Internet.
                      # CLI: ip route add table 0 <tenant-subnet> via
                      #                                <tenant-loopback-bvi>
                      #
                      # Note(onong): Do not export an IPv4 internal network
                      # into an IPv6 external VRF.
                      int_net = ip_network(int_network)
                      if is_ipv6 and int_net.version != 6:
                          LOG.info('Not exporting tenant\'s IPv4 internal '
                                   'network into IPv6 external VRF')
                      else:
                          self.vpp.add_ip_route(
                              vrf=ext_vrf,
                              ip_address=self._pack_address(int_network),
                              prefixlen=int_port['prefixlen'],
                              next_hop_address=None,
                              next_hop_sw_if_index=int_port['bvi_if_idx'],
                              is_ipv6=is_ipv6)
                  else:
                      self.vpp.delete_ip_route(
                          vrf=int_vrf,
                          ip_address=self._pack_address(default_gw_ip),
                          prefixlen=0,
                          next_hop_address=self._pack_address(
                              external_gateway_ip),
                          next_hop_sw_if_index=gw_port['bvi_if_idx'],
                          is_ipv6=is_ipv6)
                      # Delete the exported route in tenant VRF
                      self.vpp.delete_ip_route(
                          vrf=int_vrf,
                          ip_address=self._pack_address(ext_network),
                          prefixlen=gw_port['prefixlen'],
                          next_hop_address=None,
                          next_hop_sw_if_index=gw_port['bvi_if_idx'],
                          is_ipv6=is_ipv6)
                      # Delete the exported route from the external VRF
                      self.vpp.delete_ip_route(
                          vrf=ext_vrf,
                          ip_address=self._pack_address(int_network),
                          prefixlen=int_port['prefixlen'],
                          next_hop_address=None,
                          next_hop_sw_if_index=int_port['bvi_if_idx'],
                          is_ipv6=is_ipv6)
code_tokens: def export_routes_from_tenant_vrfs ( self , source_vrf = 0 , is_add = True , ext_gw_ip = None ) : if source_vrf : LOG . debug ( "Router:Exporting external route into tenant VRF:%s" , source_vrf ) else : LOG . debug ( "Router:Exporting external route into all tenant VRFs" ) for ext_port in self . router_external_interfaces : gw_port = self . router_external_interfaces [ ext_port ] for int_port in self . router_interfaces . values ( ) : int_vrf = int_port [ 'vrf_id' ] ext_vrf = gw_port [ 'vrf_id' ] if source_vrf and int_vrf != source_vrf : continue is_ipv6 = int_port [ 'is_ipv6' ] default_gw_ip = "::" if is_ipv6 else '0.0.0.0' external_gateway_ip = gw_port [ 'external_gateway_ip' ] if ext_gw_ip and external_gateway_ip != ext_gw_ip : continue ext_network = self . _get_ip_network ( gw_port [ 'gateway_ip' ] , gw_port [ 'prefixlen' ] ) int_network = self . _get_ip_network ( int_port [ 'gateway_ip' ] , int_port [ 'prefixlen' ] ) if is_add : ext_ip = ip_address ( external_gateway_ip ) if is_ipv6 and ext_ip . version != 6 : LOG . info ( 'Not setting IPv6 default route via an IPv4' ' external gateway' ) else : self . vpp . add_ip_route ( vrf = int_vrf , ip_address = self . _pack_address ( default_gw_ip ) , prefixlen = 0 , next_hop_address = self . _pack_address ( external_gateway_ip ) , next_hop_sw_if_index = gw_port [ 'bvi_if_idx' ] , is_ipv6 = is_ipv6 ) ext_net = ip_network ( ext_network ) if is_ipv6 and ext_net . version != 6 : LOG . info ( 'Not exporting IPv4 external network into ' 'tenant\'s IPv6 VRF' ) else : self . vpp . add_ip_route ( vrf = int_vrf , ip_address = self . _pack_address ( ext_network ) , prefixlen = gw_port [ 'prefixlen' ] , next_hop_address = None , next_hop_sw_if_index = gw_port [ 'bvi_if_idx' ] , is_ipv6 = is_ipv6 ) int_net = ip_network ( int_network ) if is_ipv6 and int_net . version != 6 : LOG . info ( 'Not exporting tenant\'s IPv4 internal ' 'network into IPv6 external VRF' ) else : self . vpp . add_ip_route ( vrf = ext_vrf , ip_address = self . _pack_address ( int_network ) , prefixlen = int_port [ 'prefixlen' ] , next_hop_address = None , next_hop_sw_if_index = int_port [ 'bvi_if_idx' ] , is_ipv6 = is_ipv6 ) else : self . vpp . delete_ip_route ( vrf = int_vrf , ip_address = self . _pack_address ( default_gw_ip ) , prefixlen = 0 , next_hop_address = self . _pack_address ( external_gateway_ip ) , next_hop_sw_if_index = gw_port [ 'bvi_if_idx' ] , is_ipv6 = is_ipv6 ) self . vpp . delete_ip_route ( vrf = int_vrf , ip_address = self . _pack_address ( ext_network ) , prefixlen = gw_port [ 'prefixlen' ] , next_hop_address = None , next_hop_sw_if_index = gw_port [ 'bvi_if_idx' ] , is_ipv6 = is_ipv6 ) self . vpp . delete_ip_route ( vrf = ext_vrf , ip_address = self . _pack_address ( int_network ) , prefixlen = int_port [ 'prefixlen' ] , next_hop_address = None , next_hop_sw_if_index = int_port [ 'bvi_if_idx' ] , is_ipv6 = is_ipv6 )
short_docstring: Exports the external gateway into the tenant VRF.
short_docstring_tokens: Exports the external gateway into the tenant VRF .
comment: """Exports the external gateway into the tenant VRF.
  
          The gateway network has to be exported into the tenant VRF for
          it to communicate with the outside world. Also a default route
          has to be set to the external gateway IP address.
          If source_vrf (i.e tenant VRF) is provided,
             - Export the external gateway's IP from VRF=0 into this VRF.
             - Add a default route to the external_gateway in this VRF
          Else,
             - Export the external gateway into into all tenant VRFs
             - Add a default route to the external_gateway in all tenant VRFs
          If the external gateway IP address is not provided:
          All external networks are exported into tenant VRFs
  
          """$SEP$# TODO(najoy): Check if the tenant ID matches for the gateway router$SEP$# external interface and export only matching external routes.$SEP$# If a source vrf is present only update if the VRF matches$SEP$# Get the external and internal networks in the CIDR form$SEP$# Add the default route (0.0.0.0/0) to the$SEP$# external gateway IP addr, which is outside of VPP$SEP$# with the next hop sw_if_index set to the external$SEP$# loopback BVI address.$SEP$# Note: The external loopback sw_if_index and the$SEP$# next_hop_address is mandatory here to prevent a VPP$SEP$# crash - Similar to the CLI command$SEP$# ip route add table <int-vrf> 0.0.0.0/0 via <next-hop-ip>$SEP$#                                    <next-hop-sw-indx>$SEP$#$SEP$# Note(onong): Do not set IPv6 default gateway to an IPv4$SEP$# external gateway$SEP$# Export the external gateway subnet into the tenant VRF$SEP$# to enable tenant traffic to flow out. Exporting is done$SEP$# by setting the next hop sw if index to the loopback's$SEP$# sw_index (i.e. BVI) on the external network$SEP$# CLI: ip route add table <int_vrf> <external-subnet>$SEP$#                                 via <next-hop-sw-indx>$SEP$#$SEP$# Note(onong): Do not export an IPv4 external network$SEP$# into an IPv6 VRF.$SEP$# Export the tenant network into external VRF so the$SEP$# gateway can route return traffic to the tenant VM from$SEP$# the Internet.$SEP$# CLI: ip route add table 0 <tenant-subnet> via$SEP$#                                <tenant-loopback-bvi>$SEP$#$SEP$# Note(onong): Do not export an IPv4 internal network$SEP$# into an IPv6 external VRF.$SEP$# Delete the exported route in tenant VRF$SEP$# Delete the exported route from the external VRF