def test_6_same_nlri_same_attributes_order_multivalued(self):
        # Two routes with same NLRI but and same attributes should
        # hash to the same values and be equal, *even if* for a said
        # multivalued attributes, like extended community, the values
        # appear in a distinct order

        atts1 = exa.Attributes()
        ecoms1 = exa.ExtendedCommunities()
        ecoms1.communities.append(exa.RouteTarget(64512, 1))
        ecoms1.communities.append(
            exa.Encapsulation(exa.Encapsulation.Type.VXLAN))
        ecoms1.communities.append(exa.RouteTarget(64512, 2))
        atts1.add(ecoms1)

        atts2 = exa.Attributes()
        ecoms2 = exa.ExtendedCommunities()
        ecoms2.communities.append(exa.RouteTarget(64512, 2))
        ecoms2.communities.append(exa.RouteTarget(64512, 1))
        ecoms2.communities.append(
            exa.Encapsulation(exa.Encapsulation.Type.VXLAN))
        atts2.add(ecoms2)

        entry1 = engine.RouteEntry(base.NLRI1, None, atts1)
        entry2 = engine.RouteEntry(base.NLRI1, None, atts2)

        self.assertEqual(hash(entry1), hash(entry2))
        self.assertEqual(entry1, entry2)
    def test_10_ecoms(self):
        ecoms1 = exa.ExtendedCommunities()
        ecoms1.communities.append(
            exa.Encapsulation(exa.Encapsulation.Type.VXLAN))
        atts1 = exa.Attributes()
        atts1.add(ecoms1)

        ecoms2 = exa.ExtendedCommunities()
        ecoms2.communities.append(
            exa.Encapsulation(exa.Encapsulation.Type.VXLAN))
        ecoms2.communities.append(exa.RouteTarget(64512, 1))
        atts2 = exa.Attributes()
        atts2.add(ecoms2)

        self.assertFalse(atts1.sameValuesAs(atts2))
        self.assertFalse(atts2.sameValuesAs(atts1))
    def test_8_route_entry_set_rts(self):
        atts = exa.Attributes()
        ecoms = exa.ExtendedCommunities()
        ecoms.communities.append(exa.RouteTarget(64512, 1))
        ecoms.communities.append(exa.RouteTarget(64512, 2))
        ecoms.communities.append(
            exa.Encapsulation(exa.Encapsulation.Type.VXLAN))
        atts.add(exa.LocalPreference(20))
        atts.add(ecoms)

        entry = engine.RouteEntry(base.NLRI1, None, atts)

        # check that the route_entry object has the RTs we wanted
        self.assertIn(exa.RouteTarget(64512, 1), entry.route_targets)
        self.assertIn(exa.RouteTarget(64512, 2), entry.route_targets)

        # modify the route targets
        entry.set_route_targets(
            [exa.RouteTarget(64512, 3),
             exa.RouteTarget(64512, 1)])

        # check that the new RTs have replaced the old ones
        self.assertIn(exa.RouteTarget(64512, 1), entry.route_targets)
        self.assertIn(exa.RouteTarget(64512, 3), entry.route_targets)
        self.assertNotIn(exa.RouteTarget(64512, 2), entry.route_targets)

        # also need to check the RTs in the attributes
        ecoms = entry.attributes[
            exa.Attribute.CODE.EXTENDED_COMMUNITY].communities
        self.assertIn(exa.RouteTarget(64512, 1), ecoms)
        self.assertIn(exa.RouteTarget(64512, 3), ecoms)
        self.assertNotIn(exa.RouteTarget(64512, 2), ecoms)

        # check that other communities were preserved
        self.assertIn(exa.Encapsulation(exa.Encapsulation.Type.VXLAN), ecoms)
    def __init__(self, nlri, rts=None, attributes=None, source=None):
        if attributes is None:
            attributes = exa.Attributes()
        assert isinstance(attributes, exa.Attributes)
        if rts is not None:
            assert isinstance(rts, list)
            assert len(rts) == 0 or isinstance(rts[0], exa.RouteTarget)

        self.source = source
        self.afi = nlri.afi
        self.safi = nlri.safi
        self.nlri = nlri
        self.attributes = attributes
        # a list of exa.bgp.message.update.attribute.community.
        #   extended.RouteTargetASN2Number
        self._route_targets = []
        if exa.Attribute.CODE.EXTENDED_COMMUNITY in self.attributes:
            ecoms = self.attributes[
                exa.Attribute.CODE.EXTENDED_COMMUNITY].communities
            # use type(..) because isinstance(rtrecord, RouteTarget) is True
            self._route_targets = [
                ecom for ecom in ecoms if type(ecom) == exa.RouteTarget
            ]
            if rts:
                ecoms += rts
                self._route_targets += rts
        else:
            if rts:
                self.attributes.add(exa.ExtendedCommunities(rts))
                self._route_targets += rts
示例#5
0
    def synthesize_vif_bgp_route(self,
                                 mac_address,
                                 ip_prefix,
                                 plen,
                                 label,
                                 lb_consistent_hash_order,
                                 route_distinguisher=None,
                                 local_pref=None):
        rd = route_distinguisher if route_distinguisher else self.instance_rd
        route_entry = self.generate_vif_bgp_route(mac_address, ip_prefix, plen,
                                                  label, rd)
        assert isinstance(route_entry, engine.RouteEntry)

        route_entry.attributes.add(self._gen_encap_extended_communities())
        route_entry.set_route_targets(self.export_rts)

        ecommunities = exa.ExtendedCommunities()
        ecommunities.communities.append(
            exa.ConsistentHashSortOrder(lb_consistent_hash_order))
        route_entry.attributes.add(ecommunities)

        route_entry.attributes.add(
            exa.LocalPreference(local_pref or DEFAULT_LOCAL_PREF))

        self.log.debug("Synthesized Vif route entry: %s", route_entry)
        return route_entry
示例#6
0
    def _new_route_event(self, event_type, nlri, rts, source, nh, lp=0,
                         replaced_route_entry=None,
                         afi=exa.AFI(exa.AFI.ipv4),
                         safi=exa.SAFI(exa.SAFI.mpls_vpn),
                         **kwargs):
        attributes = exa.Attributes()
        attributes.add(exa.NextHop(nh))
        attributes.add(exa.LocalPreference(lp))

        if 'rtrecords' in kwargs:
            ecoms = exa.ExtendedCommunities()
            ecoms.communities += kwargs['rtrecords']
            attributes.add(ecoms)

        route_event = engine.RouteEvent(event_type,
                                        engine.RouteEntry(nlri, rts,
                                                          attributes, source),
                                        source)
        route_event.set_replaced_route(replaced_route_entry)

        LOG.info("*** Emitting event to %s: %s",
                 self.event_target_worker, route_event)

        self.event_target_worker._on_event(route_event)

        return route_event
示例#7
0
    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 set_route_targets(self, route_targets):
        # first build a list of ecoms without any RT
        ecoms = self.ecoms(lambda ecom: not isinstance(ecom, exa.RouteTarget))

        # then add the right RTs
        new_ecoms = exa.ExtendedCommunities()
        new_ecoms.communities += ecoms
        new_ecoms.communities += route_targets

        # update
        self._route_targets = route_targets

        self.attributes.remove(new_ecoms.ID)
        self.attributes.add(new_ecoms)
    def test_9_route_entry_rts_as_init_param(self):
        atts = exa.Attributes()
        ecoms = exa.ExtendedCommunities()
        ecoms.communities.append(
            exa.Encapsulation(exa.Encapsulation.Type.VXLAN))
        atts.add(exa.LocalPreference(20))
        atts.add(ecoms)

        rts = [exa.RouteTarget(64512, 1), exa.RouteTarget(64512, 2)]

        entry = engine.RouteEntry(base.NLRI1, rts, atts)

        self.assertIn(exa.RouteTarget(64512, 1), entry.route_targets)
        self.assertIn(exa.RouteTarget(64512, 2), entry.route_targets)

        ecoms = entry.attributes[
            exa.Attribute.CODE.EXTENDED_COMMUNITY].communities
        self.assertIn(exa.RouteTarget(64512, 1), ecoms)
        self.assertIn(exa.RouteTarget(64512, 2), ecoms)
        self.assertIn(exa.Encapsulation(exa.Encapsulation.Type.VXLAN), ecoms)
示例#10
0
    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
示例#11
0
    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
示例#12
0
    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