def messages(self, negotiated): # sort the nlris add_nlri = [] del_nlri = [] add_mp = {} del_mp = {} for nlri in self.nlris: if nlri.family() in negotiated.families: if nlri.afi == AFI.ipv4 and nlri.safi in [ SAFI.unicast, SAFI.multicast ]: if nlri.action == OUT.announce: add_nlri.append(nlri) else: del_nlri.append(nlri) else: if nlri.action == OUT.announce: add_mp.setdefault(nlri.family(), []).append(nlri) else: del_mp.setdefault(nlri.family(), []).append(nlri) if not add_nlri and not del_nlri and not add_mp and not del_mp: return if add_nlri or add_mp: attr = self.attributes.pack(negotiated, True) else: attr = '' # withdrawn IPv4 packed_del = '' msg_size = negotiated.msg_size - 19 - 2 - 2 # 2 bytes for each of the two prefix() header addpath = negotiated.addpath.send(AFI.ipv4, SAFI.unicast) while del_nlri: nlri = del_nlri.pop() packed = nlri.pack(addpath) if len(packed_del + packed) >= msg_size: if not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack one NLRI' ) yield self._message(prefix(packed_del) + prefix('')) packed_del = packed else: packed_del += packed # withdrawn MP packed_mp_del = '' families = del_mp.keys() while families: family = families.pop() mps = del_mp[family] addpath = negotiated.addpath.send(*family) mp_packed_generator = MPURNLRI(mps).packed_attributes(addpath) try: while True: packed = mp_packed_generator.next() if len(packed_del + packed_mp_del + packed) >= msg_size: if not packed_mp_del and not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack one MPURNLRI' ) yield self._message( prefix(packed_del) + prefix(packed_mp_del)) packed_del = '' packed_mp_del = packed else: packed_mp_del += packed except StopIteration: pass # add MP # we have some MPRNLRI so we need to add the attributes, recalculate # and make sure we do not overflow packed_mp_add = '' if add_mp: msg_size = negotiated.msg_size - 19 - 2 - 2 - len( attr) # 2 bytes for each of the two prefix() header if len(packed_del + packed_mp_del) >= msg_size: yield self._message(prefix(packed_del) + prefix(packed_mp_del)) packed_del = '' packed_mp_del = '' families = add_mp.keys() while families: family = families.pop() mps = add_mp[family] addpath = negotiated.addpath.send(*family) mp_packed_generator = MPRNLRI(mps).packed_attributes(addpath) try: while True: packed = mp_packed_generator.next() if len(packed_del + packed_mp_del + packed_mp_add + packed) >= msg_size: if not packed_mp_add and not packed_mp_del and not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack on MPURNLRI' ) yield self._message( prefix(packed_del) + prefix(attr + packed_mp_del + packed_mp_add)) packed_del = '' packed_mp_del = '' packed_mp_add = packed else: packed_mp_add += packed except StopIteration: pass # ADD Ipv4 packed_add = '' if add_nlri: msg_size = negotiated.msg_size - 19 - 2 - 2 - len( attr) # 2 bytes for each of the two prefix() header if len(packed_del + packed_mp_del + packed_mp_add) >= msg_size: yield self._message(prefix(packed_del) + prefix(packed_mp_del)) packed_del = '' packed_mp_del = '' addpath = negotiated.addpath.send(AFI.ipv4, SAFI.unicast) while add_nlri: nlri = add_nlri.pop() packed = nlri.pack(addpath) if len(packed_del + packed_mp_del + packed_mp_add + packed_add + packed) >= msg_size: if not packed_add and not packed_mp_add and not packed_mp_del and not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack one NLRI' ) if packed_mp_add: yield self._message( prefix(packed_del) + prefix(attr + packed_mp_del + packed_mp_add) + packed_add) msg_size = negotiated.msg_size - 19 - 2 - 2 # 2 bytes for each of the two prefix() header else: yield self._message( prefix(packed_del) + prefix(attr + packed_mp_del) + packed_add) packed_del = '' packed_mp_del = '' packed_mp_add = '' packed_add = packed else: packed_add += packed yield self._message( prefix(packed_del) + prefix(attr + packed_mp_del + packed_mp_add) + packed_add)
def messages(self, negotiated): attributes = '' asn4 = negotiated.asn4 local_as = negotiated.local_as peer_as = negotiated.peer_as msg_size = negotiated.msg_size - 2 - 2 # 2 bytes for each of the two prefix() header # sort the nlris add_nlri = [] del_nlri = [] add_mp = {} del_mp = {} for nlri in self.nlris: if nlri.family() in negotiated.families: if nlri.afi == AFI.ipv4 and nlri.safi in [ SAFI.unicast, SAFI.multicast ]: if nlri.action == OUT.announce: add_nlri.append(nlri) else: del_nlri.append(nlri) else: if nlri.action == OUT.announce: add_mp.setdefault(nlri.family(), []).append(nlri) else: del_mp.setdefault(nlri.family(), []).append(nlri) if not add_nlri and not del_nlri and not add_mp and not del_mp: return if add_nlri: attr = self.attributes.pack(asn4, local_as, peer_as, True) elif add_mp: add_default = False for afi, safi in add_mp: if safi not in (SAFI.flow_ip, SAFI.flow_vpn): add_default = True attr = self.attributes.pack(asn4, local_as, peer_as, add_default) else: attr = '' # generate the message packed_del = '' packed_mp_del = '' packed_mp_add = '' packed_add = '' # withdrawn IPv4 addpath = negotiated.addpath.send(AFI.ipv4, SAFI.unicast) while del_nlri: nlri = del_nlri.pop() packed = nlri.pack(addpath) if len(packed_del + packed) > msg_size: if not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack one NLRI' ) yield self._message(prefix(packed_del)) packed_del = packed else: packed_del += packed # withdrawn MP families = del_mp.keys() while families: family = families.pop() mps = del_mp[family] addpath = negotiated.addpath.send(*family) mp_packed_generator = MPURNLRI(mps).packed_attributes(addpath) try: while True: packed = mp_packed_generator.next() if len(packed_del + packed_mp_del + packed) > msg_size: if not packed_mp_del and not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack one MPURNLRI' ) yield self._message( prefix(packed_del) + prefix(packed_mp_del)) packed_del = '' packed_mp_del = packed else: packed_mp_del += packed except StopIteration: pass # we have some MPRNLRI so we need to add the attributes, recalculate # and make sure we do not overflow if add_mp: msg_size = negotiated.msg_size - 2 - 2 - len( attr) # 2 bytes for each of the two prefix() header if len(packed_del + packed_mp_del) > msg_size: yield self._message(prefix(packed_del) + prefix(packed_mp_del)) packed_del = '' packed_mp_del = '' # add MP families = add_mp.keys() while families: family = families.pop() mps = add_mp[family] addpath = negotiated.addpath.send(*family) mp_packed_generator = MPRNLRI(mps).packed_attributes(addpath) try: while True: packed = mp_packed_generator.next() if len(packed_del + packed_mp_del + packed_mp_add + packed) > msg_size: if not packed_mp_add and not packed_mp_del and not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack on MPURNLRI' ) yield self._message( prefix(packed_del) + prefix(attributes + packed_mp_del + packed_mp_add)) packed_del = '' packed_mp_del = '' packed_mp_add = packed if family not in ((AFI.ipv4, SAFI.flow_ip), (AFI.ipv4, SAFI.flow_vpn)): attributes = attr else: attributes = '' else: packed_mp_add += packed attributes = attr except StopIteration: pass # recalculate size if we do not have any more attributes to send if not packed_mp_add: msg_size = negotiated.msg_size - 2 - 2 # 2 bytes for each of the two prefix() header # ADD Ipv4 addpath = negotiated.addpath.send(AFI.ipv4, SAFI.unicast) while add_nlri: nlri = add_nlri.pop() packed = nlri.pack(addpath) if len(packed_del + packed_mp_del + packed_mp_add + packed_add + packed) > msg_size: if not packed_add and not packed_mp_add and not packed_mp_del and not packed_del: raise Notify( 6, 0, 'attributes size is so large we can not even pack one NLRI' ) if packed_mp_add: yield self._message( prefix(packed_del) + prefix(attributes + packed_mp_del + packed_mp_add) + packed_add) msg_size = negotiated.msg_size - 2 - 2 # 2 bytes for each of the two prefix() header else: yield self._message( prefix(packed_del) + prefix(packed_mp_del) + packed_add) packed_del = '' packed_mp_del = '' packed_mp_add = '' packed_add = packed attributes = attr else: packed_add += packed attributes = attr yield self._message( prefix(packed_del) + prefix(attributes + packed_mp_del + packed_mp_add) + packed_add)
def messages (self, negotiated): # sort the nlris add_nlri = [] del_nlri = [] add_mp = {} del_mp = {} for nlri in self.nlris: if nlri.family() in negotiated.families: if nlri.afi == AFI.ipv4 and nlri.safi in [SAFI.unicast, SAFI.multicast]: if nlri.action == OUT.ANNOUNCE: add_nlri.append(nlri) else: del_nlri.append(nlri) else: if nlri.action == OUT.ANNOUNCE: add_mp.setdefault(nlri.family(),[]).append(nlri) else: del_mp.setdefault(nlri.family(),[]).append(nlri) if not add_nlri and not del_nlri and not add_mp and not del_mp: return if add_nlri or add_mp: attr = self.attributes.pack(negotiated,True) else: attr = '' # withdrawn IPv4 packed_del = '' msg_size = negotiated.msg_size - 19 - 2 - 2 # 2 bytes for each of the two prefix() header addpath = negotiated.addpath.send(AFI.ipv4,SAFI.unicast) while del_nlri: nlri = del_nlri.pop() packed = nlri.pack(addpath) seen_size = len(packed_del + packed) if seen_size > msg_size: if not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack one NLRI') yield self._message(Update.prefix(packed_del) + Update.prefix('')) packed_del = packed else: packed_del += packed # withdrawn MP packed_mp_del = '' families = del_mp.keys() while families: family = families.pop() afi,safi = family mps = del_mp[family] addpath = negotiated.addpath.send(*family) seen_size = len(packed_del + packed_mp_del) mp_packed_generator = MPURNLRI(afi,safi,mps).packed_attributes(addpath,msg_size-seen_size) try: while True: packed = mp_packed_generator.next() seen_size = len(packed_del + packed_mp_del + packed) if seen_size > msg_size: if not packed_mp_del and not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack one MPURNLRI') yield self._message(Update.prefix(packed_del) + Update.prefix(packed_mp_del)) packed_del = '' packed_mp_del = packed else: packed_mp_del += packed except StopIteration: pass # add MP # we have some MPRNLRI so we need to add the attributes, recalculate # and make sure we do not overflow packed_mp_add = '' if add_mp: msg_size = negotiated.msg_size - 19 - 2 - 2 - len(attr) # 2 bytes for each of the two prefix() header seen_size = len(packed_del + packed_mp_del) if seen_size > msg_size: yield self._message(Update.prefix(packed_del) + Update.prefix(packed_mp_del)) packed_del = '' packed_mp_del = '' families = add_mp.keys() while families: family = families.pop() afi,safi = family mps = add_mp[family] addpath = negotiated.addpath.send(*family) seen_size = len(packed_del + packed_mp_del + packed_mp_add) mp_packed_generator = MPRNLRI(afi,safi,mps).packed_attributes(addpath,msg_size-seen_size) try: while True: packed = mp_packed_generator.next() seen_size = len(packed_del + packed_mp_del + packed_mp_add + packed) if seen_size > msg_size: if not packed_mp_add and not packed_mp_del and not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack on MPURNLRI') yield self._message(Update.prefix(packed_del) + Update.prefix(attr + packed_mp_del + packed_mp_add)) packed_del = '' packed_mp_del = '' packed_mp_add = packed else: packed_mp_add += packed except StopIteration: pass # ADD Ipv4 packed_add = '' if add_nlri: msg_size = negotiated.msg_size - 19 - 2 - 2 - len(attr) # 2 bytes for each of the two prefix() header seen_size = len(packed_del + packed_mp_del + packed_mp_add) if seen_size > msg_size: yield self._message(Update.prefix(packed_del) + Update.prefix(packed_mp_del)) packed_del = '' packed_mp_del = '' addpath = negotiated.addpath.send(AFI.ipv4,SAFI.unicast) while add_nlri: nlri = add_nlri.pop() packed = nlri.pack(addpath) seen_size = len(packed_del + packed_mp_del + packed_mp_add + packed_add + packed) if seen_size > msg_size: if not packed_add and not packed_mp_add and not packed_mp_del and not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack one NLRI') if packed_mp_add: yield self._message(Update.prefix(packed_del) + Update.prefix(attr + packed_mp_del + packed_mp_add) + packed_add) msg_size = negotiated.msg_size - 19 - 2 - 2 # 2 bytes for each of the two prefix() header else: yield self._message(Update.prefix(packed_del) + Update.prefix(attr + packed_mp_del) + packed_add) packed_del = '' packed_mp_del = '' packed_mp_add = '' packed_add = packed else: packed_add += packed yield self._message(Update.prefix(packed_del) + Update.prefix(attr + packed_mp_del + packed_mp_add) + packed_add)
def messages (self,negotiated): attributes = '' asn4 = negotiated.asn4 local_as = negotiated.local_as peer_as = negotiated.peer_as msg_size = negotiated.msg_size - 2 - 2 # 2 bytes for each of the two prefix() header # sort the nlris add_nlri = [] del_nlri = [] add_mp = {} del_mp = {} for nlri in self.nlris: if nlri.family() in negotiated.families: if nlri.afi == AFI.ipv4 and nlri.safi in [SAFI.unicast, SAFI.multicast]: if nlri.action == OUT.announce: add_nlri.append(nlri) else: del_nlri.append(nlri) else: if nlri.action == OUT.announce: add_mp.setdefault(nlri.family(),[]).append(nlri) else: del_mp.setdefault(nlri.family(),[]).append(nlri) if not add_nlri and not del_nlri and not add_mp and not del_mp: return if add_nlri: attr = self.attributes.pack(asn4,local_as,peer_as,True) elif add_mp: add_default = False for afi,safi in add_mp: if safi not in (SAFI.flow_ip,SAFI.flow_vpn): add_default = True attr = self.attributes.pack(asn4,local_as,peer_as,add_default) else: attr = '' # generate the message packed_del = '' packed_mp_del = '' packed_mp_add = '' packed_add = '' # withdrawn IPv4 addpath = negotiated.addpath.send(AFI.ipv4,SAFI.unicast) while del_nlri: nlri = del_nlri.pop() packed = nlri.pack(addpath) if len(packed_del + packed) > msg_size: if not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack one NLRI') yield self._message(prefix(packed_del)) packed_del = packed else: packed_del += packed # withdrawn MP families = del_mp.keys() while families: family = families.pop() mps = del_mp[family] addpath = negotiated.addpath.send(*family) mp_packed_generator = MPURNLRI(mps).packed_attributes(addpath) try: while True: packed = mp_packed_generator.next() if len(packed_del + packed_mp_del + packed) > msg_size: if not packed_mp_del and not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack one MPURNLRI') yield self._message(prefix(packed_del) + prefix(packed_mp_del)) packed_del = '' packed_mp_del = packed else: packed_mp_del += packed except StopIteration: pass # we have some MPRNLRI so we need to add the attributes, recalculate # and make sure we do not overflow if add_mp: msg_size = negotiated.msg_size - 2 - 2 - len(attr) # 2 bytes for each of the two prefix() header if len(packed_del + packed_mp_del) > msg_size: yield self._message(prefix(packed_del) + prefix(packed_mp_del)) packed_del = '' packed_mp_del = '' # add MP families = add_mp.keys() while families: family = families.pop() mps = add_mp[family] addpath = negotiated.addpath.send(*family) mp_packed_generator = MPRNLRI(mps).packed_attributes(addpath) try: while True: packed = mp_packed_generator.next() if len(packed_del + packed_mp_del + packed_mp_add + packed) > msg_size: if not packed_mp_add and not packed_mp_del and not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack on MPURNLRI') yield self._message(prefix(packed_del) + prefix(attributes + packed_mp_del + packed_mp_add)) packed_del = '' packed_mp_del = '' packed_mp_add = packed if family not in ((AFI.ipv4,SAFI.flow_ip),(AFI.ipv4,SAFI.flow_vpn)): attributes = attr else: attributes = '' else: packed_mp_add += packed attributes = attr except StopIteration: pass # recalculate size if we do not have any more attributes to send if not packed_mp_add: msg_size = negotiated.msg_size - 2 - 2 # 2 bytes for each of the two prefix() header # ADD Ipv4 addpath = negotiated.addpath.send(AFI.ipv4,SAFI.unicast) while add_nlri: nlri = add_nlri.pop() packed = nlri.pack(addpath) if len(packed_del + packed_mp_del + packed_mp_add + packed_add + packed) > msg_size: if not packed_add and not packed_mp_add and not packed_mp_del and not packed_del: raise Notify(6,0,'attributes size is so large we can not even pack one NLRI') if packed_mp_add: yield self._message(prefix(packed_del) + prefix(attributes + packed_mp_del + packed_mp_add) + packed_add) msg_size = negotiated.msg_size - 2 - 2 # 2 bytes for each of the two prefix() header else: yield self._message(prefix(packed_del) + prefix(packed_mp_del) + packed_add) packed_del = '' packed_mp_del = '' packed_mp_add = '' packed_add = packed attributes = attr else: packed_add += packed attributes = attr yield self._message(prefix(packed_del) + prefix(attributes + packed_mp_del + packed_mp_add) + packed_add)