def _new_flow_event(self, event_type, nlri, to_rts, attract_rts, source, afi=exa.AFI(exa.AFI.ipv4), safi=exa.SAFI(exa.SAFI.flow_vpn), **kwargs): attributes = exa.Attributes() ecommunities = exa.ExtendedCommunities() ecommunities.communities.append( exa.TrafficRedirect(exa.ASN(int(to_rts[0].asn)), int(to_rts[0].number)) ) attributes.add(ecommunities) flow_event = engine.RouteEvent(event_type, engine.RouteEntry(nlri, attract_rts, attributes, source), source) self.event_target_worker.enqueue(flow_event) LOG.info("*** Emitting FlowSpec event to %s: %s", self.event_target_worker, flow_event) self._wait() return flow_event
def _redirect_route_for_readvertisement(self, route): # Create a FlowSpec NLRI with distinct RD and a copy of rules from # FlowSpec route to readvertise nlri = flowspec.FlowRouteFactory(self.afi, self.instance_rd) nlri.rules = route.nlri.rules attributes = exa.Attributes() ecoms = exa.ExtendedCommunities() ecoms.communities += (self._gen_rtrecords_extended_community( route.ecoms)) assert len(self.attract_rts) == 1 rt = self.attract_rts[0] ecoms.communities.append( exa.TrafficRedirect(exa.ASN(int(rt.asn)), int(rt.number))) attributes.add(ecoms) entry = engine.RouteEntry(nlri, self.readvertise_to_rts, attributes) self.log.debug("RouteEntry for redirect (re-)advertisement: %s", entry) return entry
def _new_flow_event(self, event_type, nlri, to_rts, attract_rts, source, afi=exa.AFI(exa.AFI.ipv4), safi=exa.SAFI(exa.SAFI.flow_vpn), **kwargs): attributes = exa.Attributes() ecommunities = exa.ExtendedCommunities() ecommunities.communities.append( exa.TrafficRedirect(exa.ASN(int(to_rts[0].asn)), int(to_rts[0].number)) ) attributes.add(ecommunities) flow_event = engine.RouteEvent(event_type, engine.RouteEntry(nlri, attract_rts, attributes, source), source) self.event_target_worker._on_event(flow_event) return flow_event
def synthesize_redirect_bgp_route(self, rules): self.log.info("synthesize_redirect_bgp_route called for rules %s", rules) nlri = flowspec.FlowRouteFactory(self.afi, self.instance_rd) for rule in rules: nlri.add(rule) route_entry = engine.RouteEntry(nlri) assert isinstance(route_entry, engine.RouteEntry) ecommunities = exa.ExtendedCommunities() # checked at __init__: assert len(self.readvertise_to_rts) == 1 rt = self.readvertise_to_rts[0] ecommunities.communities.append( exa.TrafficRedirect(exa.ASN(int(rt.asn)), int(rt.number))) route_entry.attributes.add(ecommunities) route_entry.set_route_targets(self.attract_rts) self.log.debug("Synthesized redirect route entry: %s", route_entry) return route_entry
def _initiate_connection(self): self.log.debug("Initiate ExaBGP connection to %s:%s from %s", self.peer_address, cfg.CONF.BGP.bgp_port, self.local_address) self.rtc_active = False neighbor = exa_neighbor.Neighbor() neighbor.make_rib() neighbor.router_id = exa_open.RouterID(self.local_address) neighbor.local_as = exa.ASN(cfg.CONF.BGP.my_as) # no support for eBGP yet: neighbor.peer_as = exa.ASN(cfg.CONF.BGP.my_as) neighbor.local_address = exa.IP.create(self.local_address) neighbor.md5_ip = exa.IP.create(self.local_address) neighbor.peer_address = exa.IP.create(self.peer_address) neighbor.hold_time = exa_open.HoldTime( bgp_peer_worker.DEFAULT_HOLDTIME) neighbor.connect = cfg.CONF.BGP.bgp_port neighbor.api = collections.defaultdict(list) for afi_safi in self.enabled_families: neighbor.add_family(afi_safi) if cfg.CONF.BGP.enable_rtc: neighbor.add_family( (exa.AFI(exa.AFI.ipv4), exa.SAFI(exa.SAFI.rtc))) self.log.debug("Instantiate ExaBGP Peer") self.peer = exa_peer.Peer(neighbor, None) try: for action in self.peer._connect(): self.fsm.state = TRANSLATE_EXABGP_STATE[ self.peer._outgoing.fsm.state] if action == exa_peer.ACTION.LATER: time.sleep(2) elif action == exa_peer.ACTION.NOW: time.sleep(0.1) if self.should_stop: self.log.debug("We're closing, raise StoppedException") raise bgp_peer_worker.StoppedException() if action == exa_peer.ACTION.CLOSE: self.log.debug("Socket status is CLOSE, " "raise InitiateConnectionException") raise bgp_peer_worker.InitiateConnectionException( "Socket is closed") except exa_peer.Interrupted: self.log.debug("Connect was interrupted, " "raise InitiateConnectionException") raise bgp_peer_worker.InitiateConnectionException( "Connect was interrupted") except exa_message.Notify as e: self.log.debug("Notify: %s", e) if (e.code, e.subcode) == (1, 1): raise bgp_peer_worker.OpenWaitTimeout(str(e)) else: raise Exception("Notify received: %s" % e) except exa_reactor.network.error.LostConnection as e: raise # check the capabilities of the session just established... self.protocol = self.peer._outgoing.proto received_open = self.protocol.negotiated.received_open self._set_hold_time(self.protocol.negotiated.holdtime) mp_capabilities = received_open.capabilities.get( exa_open.capability.Capability.CODE.MULTIPROTOCOL, []) # check that our peer advertized at least mpls_vpn and evpn # capabilities self._active_families = [] for (afi, safi) in (self.__class__.enabled_families + [(exa.AFI(exa.AFI.ipv4), exa.SAFI(exa.SAFI.rtc))]): if (afi, safi) not in mp_capabilities: if (((afi, safi) != (exa.AFI(exa.AFI.ipv4), exa.SAFI(exa.SAFI.rtc))) or cfg.CONF.BGP.enable_rtc): self.log.warning( "Peer does not advertise (%s,%s) " "capability", afi, safi) else: self.log.info( "Family (%s,%s) successfully negotiated with peer %s", afi, safi, self.peer_address) self._active_families.append((afi, safi)) if len(self._active_families) == 0: self.log.error("No family was negotiated for VPN routes") self.rtc_active = False if cfg.CONF.BGP.enable_rtc: if (exa.AFI(exa.AFI.ipv4), exa.SAFI(exa.SAFI.rtc)) in mp_capabilities: self.log.info("RTC successfully enabled with peer %s", self.peer_address) self.rtc_active = True else: self.log.warning( "enable_rtc True but peer not configured for RTC")