Signed-off-by: ISHIDA Wataru <[email protected]>
---
 ryu/services/protocols/bgp/peer.py |  211 ++++++++----------------------------
 1 file changed, 45 insertions(+), 166 deletions(-)

diff --git a/ryu/services/protocols/bgp/peer.py 
b/ryu/services/protocols/bgp/peer.py
index 4bca616..224dd8d 100644
--- a/ryu/services/protocols/bgp/peer.py
+++ b/ryu/services/protocols/bgp/peer.py
@@ -588,14 +588,6 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
         """Construct update message with Outgoing-routes path attribute
         appropriately cloned/copied/updated.
         """
-        if self._neigh_conf.cap_mbgp_ipv4:
-            update = self._construct_bgp4_update(outgoing_route)
-        else:
-            update = self._construct_mpbgp_update(outgoing_route)
-
-        return update
-
-    def _construct_bgp4_update(self, outgoing_route):
         update = None
         path = outgoing_route.path
         # Get copy of path's path attributes.
@@ -603,8 +595,14 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
         new_pathattr = []
 
         if path.is_withdraw:
-            update = BGPUpdate(withdrawn_routes=[path.nlri])
-            return update
+            if self._neigh_conf.cap_mbgp_ipv4:
+                update = BGPUpdate(withdrawn_routes=[path.nlri])
+                return update
+            else:
+                mpunreach_attr = BGPPathAttributeMpUnreachNLRI(
+                    path.route_family.afi, path.route_family.safi, [path.nlri]
+                )
+                new_pathattr.append(mpunreach_attr)
         else:
             # Supported and un-supported/unknown attributes.
             origin_attr = None
@@ -629,6 +627,15 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
             nexthop_attr = BGPPathAttributeNextHop(next_hop)
             assert nexthop_attr, 'Missing NEXTHOP mandatory attribute.'
 
+            if not self._neigh_conf.cap_mbgp_ipv4:
+                # We construct mpreach-nlri attribute.
+                mpnlri_attr = BGPPathAttributeMpReachNLRI(
+                    path.route_family.afi,
+                    path.route_family.safi,
+                    next_hop,
+                    nlri_list
+                )
+
             # ORIGIN Attribute.
             # According to RFC this attribute value SHOULD NOT be changed by
             # any other speaker.
@@ -705,12 +712,27 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
             if path_extcomm_attr:
                 # SOO list can be configured per VRF and/or per Neighbor.
                 # NeighborConf has this setting we add this to existing list.
-                soo_list = path_extcomm_attr.soo_list
+                communities = path_extcomm_attr.communities
                 if self._neigh_conf.soo_list:
-                    soo_list.extend(self._neigh_conf.soo_list)
+                    #construct extended community
+                    soo_list = self._neigh_conf.soo_list
+                    subtype = 0x03
+                    for soo in soo_list:
+                        first, second = soo.split(':')
+                        if '.' in first:
+                            c = BGPIPv4AddressSpecificExtendedCommunity(
+                                subtype=subtype,
+                                ipv4_address=first,
+                                local_administrator=int(second))
+                        else:
+                            c = BGPTwoOctetAsSpecificExtendedCommunity(
+                                subtype=subtype,
+                                as_number=int(first),
+                                local_administrator=int(second))
+                        communities.append(c)
+
                 extcomm_attr = BGPPathAttributeExtendedCommunities(
-                    path_extcomm_attr.rt_list,
-                    soo_list
+                    communities=communities
                 )
 
             # UNKOWN Attributes.
@@ -720,158 +742,11 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
             # Ordering path attributes according to type as RFC says. We set
             # MPReachNLRI first as advised by experts as a new trend in BGP
             # implementation.
-            new_pathattr.append(nexthop_attr)
-            new_pathattr.append(origin_attr)
-            new_pathattr.append(aspath_attr)
-            if multi_exit_disc:
-                new_pathattr.append(multi_exit_disc)
-            if localpref_attr:
-                new_pathattr.append(localpref_attr)
-            if community_attr:
-                new_pathattr.append(community_attr)
-            if extcomm_attr:
-                new_pathattr.append(extcomm_attr)
-            if unkown_opttrans_attrs:
-                new_pathattr.extend(unkown_opttrans_attrs.values())
-
-            update = BGPUpdate(path_attributes=new_pathattr,
-                               nlri=nlri_list)
-            return update
-
-    def _construct_mpbgp_update(self, outgoing_route):
-        """Construct update message with Outgoing-routes path attribute
-        appropriately cloned/copied/updated.
-        """
-        # TODO(PH): Investigate how this case needs to be handled for iBGP.
-        update = None
-        path = outgoing_route.path
-        # Get copy of path's path attributes.
-        pathattr_map = path.pathattr_map
-        new_pathattr = []
-
-        # If this is withdraw update we copy MpUnReach path-attribute and
-        # create new Update message.
-        if path.is_withdraw:
-            # MP_UNREACH_NLRI Attribute.
-            mpunreach_attr = BGPPathAttributeMpUnreachNLRI(
-                path.route_family.afi, path.route_family.safi, [path.nlri]
-            )
-            new_pathattr.append(mpunreach_attr)
-        else:
-            # Supported and un-supported/unknown attributes.
-            origin_attr = None
-            aspath_attr = None
-            mpnlri_attr = None
-            extcomm_attr = None
-            community_attr = None
-            localpref_attr = None
-            unkown_opttrans_attrs = None
-
-            # MP_REACH_NLRI Attribute.
-            # By default we use BGPS's interface IP with this peer as next_hop.
-            # TODO(PH): change to use protocol's local address.
-            # next_hop = self._neigh_conf.host_bind_ip
-            next_hop = self._session_next_hop(path.route_family)
-            # If this is a iBGP peer.
-            if not self.is_ebgp_peer() and path.source is not None:
-                # If the path came from a bgp peer and not from NC, according
-                # to RFC 4271 we should not modify next_hop.
-                next_hop = path.nexthop
-            # We construct mpreach-nlri attribute.
-            mpnlri_attr = BGPPathAttributeMpReachNLRI(
-                path.route_family.afi,
-                path.route_family.safi,
-                next_hop,
-                [path.nlri]
-            )
-
-            # ORIGIN Attribute.
-            # According to RFC this attribute value SHOULD NOT be changed by
-            # any other speaker.
-            origin_attr = pathattr_map.get(BGP_ATTR_TYPE_ORIGIN)
-            assert origin_attr, 'Missing ORIGIN mandatory attribute.'
-
-            # AS_PATH Attribute.
-            # Construct AS-path-attr using paths aspath attr. with local AS as
-            # first item.
-            path_aspath = pathattr_map.get(BGP_ATTR_TYPE_AS_PATH)
-            assert path_aspath, 'Missing AS_PATH mandatory attribute.'
-            # Deep copy aspath_attr value
-            path_seg_list = path_aspath.path_seg_list
-            # If this is a iBGP peer.
-            if not self.is_ebgp_peer():
-                # When a given BGP speaker advertises the route to an internal
-                # peer, the advertising speaker SHALL NOT modify the AS_PATH
-                # attribute associated with the route.
-                aspath_attr = BGPPathAttributeAsPath(path_seg_list)
+            if self._neigh_conf.cap_mbgp_ipv4:
+                new_pathattr.append(nexthop_attr)
             else:
-                # When a given BGP speaker advertises the route to an external
-                # peer, the advertising speaker updates the AS_PATH attribute
-                # as follows:
-                # 1) if the first path segment of the AS_PATH is of type
-                #    AS_SEQUENCE, the local system prepends its own AS num as
-                #    the last element of the sequence (put it in the left-most
-                #    position with respect to the position of  octets in the
-                #    protocol message).  If the act of prepending will cause an
-                #    overflow in the AS_PATH segment (i.e.,  more than 255
-                #    ASes), it SHOULD prepend a new segment of type AS_SEQUENCE
-                #    and prepend its own AS number to this new segment.
-                #
-                # 2) if the first path segment of the AS_PATH is of type AS_SET
-                #    , the local system prepends a new path segment of type
-                #    AS_SEQUENCE to the AS_PATH, including its own AS number in
-                #    that segment.
-                #
-                # 3) if the AS_PATH is empty, the local system creates a path
-                #    segment of type AS_SEQUENCE, places its own AS into that
-                #    segment, and places that segment into the AS_PATH.
-                if (len(path_seg_list) > 0 and
-                        isinstance(path_seg_list[0], list) and
-                        len(path_seg_list[0]) < 255):
-                    path_seg_list[0].insert(0, self._core_service.asn)
-                else:
-                    path_seg_list.insert(0, [self._core_service.asn])
-                aspath_attr = BGPPathAttributeAsPath(path_seg_list)
-
-            # MULTI_EXIT_DISC Attribute.
-            # For eBGP session we can send multi-exit-disc if configured.
-            multi_exit_disc = None
-            if self.is_ebgp_peer():
-                multi_exit_disc = pathattr_map.get(
-                    BGP_ATTR_TYPE_MULTI_EXIT_DISC)
-
-            # LOCAL_PREF Attribute.
-            if not self.is_ebgp_peer():
-                # For iBGP peers we are required to send local-pref attribute
-                # for connected or local prefixes. We send default local-pref.
-                localpref_attr = pathattr.LocalPref(100)
+                new_pathattr.append(mpnlri_attr)
 
-            # COMMUNITY Attribute.
-            community_attr = pathattr_map.get(BGP_ATTR_TYPE_COMMUNITIES)
-
-            # EXTENDED COMMUNITY Attribute.
-            # Construct ExtCommunity path-attr based on given.
-            path_extcomm_attr = pathattr_map.get(
-                BGP_ATTR_TYPE_EXTENDED_COMMUNITIES
-            )
-            if path_extcomm_attr:
-                # SOO list can be configured per VRF and/or per Neighbor.
-                # NeighborConf has this setting we add this to existing list.
-                soo_list = path_extcomm_attr.soo_list
-                if self._neigh_conf.soo_list:
-                    soo_list.extend(self._neigh_conf.soo_list)
-                extcomm_attr = BGPPathAttributeExtendedCommunities(
-                    path_extcomm_attr.rt_list+soo_list
-                )
-
-            # UNKOWN Attributes.
-            # Get optional transitive path attributes
-            unkown_opttrans_attrs = bgp_utils.get_unknow_opttrans_attr(path)
-
-            # Ordering path attributes according to type as RFC says. We set
-            # MPReachNLRI first as advised by experts as a new trend in BGP
-            # implementation.
-            new_pathattr.append(mpnlri_attr)
             new_pathattr.append(origin_attr)
             new_pathattr.append(aspath_attr)
             if multi_exit_disc:
@@ -885,8 +760,12 @@ class Peer(Source, Sink, NeighborConfListener, Activity):
             if unkown_opttrans_attrs:
                 new_pathattr.extend(unkown_opttrans_attrs.values())
 
-        update = BGPUpdate(path_attributes=new_pathattr)
-        return update
+            if self._neigh_conf.cap_mbgp_ipv4:
+                update = BGPUpdate(path_attributes=new_pathattr,
+                                   nlri=nlri_list)
+            else:
+                update = BGPUpdate(path_attributes=new_pathattr)
+            return update
 
     def _connect_loop(self, client_factory):
         """In the current greeenlet we try to establish connection with peer.
-- 
1.7.9.5


------------------------------------------------------------------------------
Start Your Social Network Today - Download eXo Platform
Build your Enterprise Intranet with eXo Platform Software
Java Based Open Source Intranet - Social, Extensible, Cloud Ready
Get Started Now And Turn Your Intranet Into A Collaboration Platform
http://p.sf.net/sfu/ExoPlatform
_______________________________________________
Ryu-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/ryu-devel

Reply via email to