def unpack_nlri(cls, afi, safi, bgp, action, addpath): nlri = cls(afi, safi, action) if addpath: nlri.path_info = PathInfo(bgp[:4]) bgp = bgp[4:] mask = bgp[0] bgp = bgp[1:] _, rd_size = Family.size.get((afi, safi), (0, 0)) rd_mask = rd_size * 8 if safi.has_label(): labels = [] while mask - rd_mask >= 24: label = int(unpack('!L', bytes([0]) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.WITHDRAWN: break # This is a next-hop if label == 0x000000: break if label & 1: break nlri.labels = Labels(labels) if rd_size: mask -= rd_mask # the route distinguisher rd = bgp[:rd_size] bgp = bgp[rd_size:] nlri.rd = RouteDistinguisher(rd) if mask < 0: raise Notify(3, 10, 'invalid length in NLRI prefix') if not bgp and mask: raise Notify( 3, 10, 'not enough data for the mask provided to decode the NLRI') size = CIDR.size(mask) if len(bgp) < size: raise Notify( 3, 10, 'could not decode route with family %s (AFI %d) %s (SAFI %d)' % (AFI(afi), int(afi), SAFI(safi), int(safi))) network, bgp = bgp[:size], bgp[size:] nlri.cidr = CIDR(network + bytes(IP.length(afi) - size), mask) return nlri, bgp
def unpack_nlri(cls, afi, safi, bgp, action, addpath): nlri = cls(afi, safi, action) if addpath: nlri.path_info = PathInfo(bgp[:4]) bgp = bgp[4:] mask = ord(bgp[0]) bgp = bgp[1:] if cls.has_label(): labels = [] while bgp and mask >= 8: label = int(unpack('!L', chr(0) + bgp[:3])[0]) bgp = bgp[3:] mask -= 24 # 3 bytes # The last 4 bits are the bottom of Stack # The last bit is set for the last label labels.append(label >> 4) # This is a route withdrawal if label == 0x800000 and action == IN.WITHDRAWN: break # This is a next-hop if label == 0x000000: break if label & 1: break nlri.labels = Labels(labels) if cls.has_rd(): mask -= 8 * 8 # the 8 bytes of the route distinguisher rd = bgp[:8] bgp = bgp[8:] nlri.rd = RouteDistinguisher(rd) if mask < 0: raise Notify(3, 10, 'invalid length in NLRI prefix') if not bgp and mask: raise Notify( 3, 10, 'not enough data for the mask provided to decode the NLRI') size = CIDR.size(mask) if len(bgp) < size: raise Notify( 3, 10, 'could not decode route with AFI %d sand SAFI %d' % (afi, safi)) network, bgp = bgp[:size], bgp[size:] padding = '\0' * (IP.length(afi) - size) nlri.cidr = CIDR(network + padding, mask) return nlri, bgp
def unpack(cls, afi, safi, bgp, addpath, nexthop, action): labels, rd, path_identifier, mask, size, prefix, left = NLRI._nlri( afi, safi, bgp, action, addpath) nlri = cls(afi, safi, prefix, mask, nexthop, action) if labels: nlri.labels = Labels(labels) if rd: nlri.rd = RouteDistinguisher(rd) if path_identifier: nlri.path_info = PathInfo(None, None, path_identifier) return len(bgp) - len(left), nlri
def label(tokeniser): labels = [] value = tokeniser() if value == '[': while True: value = tokeniser() if value == ']': break labels.append(int(value)) else: labels.append(int(value)) return Labels(labels)
def label (tokeniser): labels = [] value = tokeniser() try: if value == '[': while True: value = tokeniser() if value == ']': break labels.append(int(value)) else: labels.append(int(value)) except ValueError: raise ValueError('invalid label %s' % value) return Labels(labels)
def label(self, scope, name, command, tokens): labels = [] label = tokens.pop(0) try: if label == '[': while True: try: label = tokens.pop(0) except IndexError: return self.error.set(self.syntax) if label == ']': break labels.append(int(label)) else: labels.append(int(label)) except ValueError: return self.error.set(self.syntax) nlri = scope[-1]['announce'][-1].nlri if not nlri.safi.has_label(): nlri.safi = SAFI(SAFI.nlri_mpls) nlri.labels = Labels(labels) return True