예제 #1
0
 def cli_detailed_attributes(self):
     # TODO: Report capabilities (is it possible to report the unknown ones too?"
     # TODO: Report neighbor direction in show command
     if self.neighbor_system_id:
         your_system_id_str = utils.system_id_str(self.neighbor_system_id)
     else:
         your_system_id_str = ""
     if self.neighbor_link_id:
         your_link_id_str = "{}".format(self.neighbor_link_id)
     else:
         your_link_id_str = ""
     attributes = [
         ["Name", self.name],
         ["System ID", utils.system_id_str(self.system_id)],
         ["IPv4 Address", self.address],
         ["LIE UDP Source Port", self.port],
         ["Link ID", self.local_id],
         ["Level", self.level],
         ["Flood UDP Port", self.flood_port],
         ["MTU", self.link_mtu_size],
         ["POD", self.pod],
         ["Hold Time", self.holdtime],
         ["Not a ZTP Offer", self.not_a_ztp_offer],
         ["You Are Not a ZTP Flood Repeater", self.not_a_ztp_offer],
         ["Your System ID", your_system_id_str],
         ["Your Local ID", your_link_id_str],
     ]
     return attributes
예제 #2
0
 def cli_details_table(self):
     # TODO: Report capabilities (is it possible to report the unknown ones too?"
     if self.neighbor_system_id:
         your_system_id_str = system_id_str(self.neighbor_system_id)
     else:
         your_system_id_str = ""
     if self.neighbor_link_id:
         your_link_id_str = "{}".format(self.neighbor_link_id)
     else:
         your_link_id_str = ""
     tab = Table(separators=False)
     tab.add_rows([
         ["Name", self.name],
         ["System ID", system_id_str(self.system_id)],
         ["IPv4 Address", self.ipv4_address],
         ["IPv6 Address", self.ipv6_address],
         ["LIE UDP Source Port", self.port],
         ["Link ID", self.local_id],
         ["Level", self.level],
         ["Flood UDP Port", self.flood_port],
         ["MTU", self.link_mtu_size],
         ["POD", self.pod],
         ["Hold Time", self.holdtime],
         ["Not a ZTP Offer", self.not_a_ztp_offer],
         ["You are Flood Repeater", self.you_are_flood_repeater],
         ["Your System ID", your_system_id_str],
         ["Your Local ID", your_link_id_str],
     ])
     return tab
예제 #3
0
 def action_process_lie(self, event_data):
     (protocol_packet, (from_address, from_port)) = event_data
     # TODO: This is a simplistic way of implementing the hold timer. Use a real timer instead.
     self._time_ticks_since_lie_received = 0
     # Sections B.1.4.1 and B.1.4.2
     new_neighbor = neighbor.Neighbor(protocol_packet, from_address, from_port)
     (accept, rule, offer_to_ztp, warning) = self.is_received_lie_acceptable(protocol_packet)
     if not accept:
         self._lie_accept_or_reject = "Rejected"
         self._lie_accept_or_reject_rule = rule
         if warning:
             self.rx_warning("Received LIE packet rejected: %s", rule)
         else:
             self.rx_info("Received LIE packet rejected: %s", rule)
         self.action_cleanup()
         if offer_to_ztp:
             self.send_offer_to_ztp_fsm(new_neighbor)
             self.fsm.push_event(self.Event.UNACCEPTABLE_HEADER)
         return
     self._lie_accept_or_reject = "Accepted"
     self._lie_accept_or_reject_rule = rule
     # Section B.1.4.3
     # Note: We send an offer to the ZTP state machine directly from here instead of pushing an
     # UPDATE_ZTP_OFFER event (see deviation DEV-2 in doc/deviations)
     self.send_offer_to_ztp_fsm(new_neighbor)
     if not self.neighbor:
         self.info("New neighbor detected with system-id %s",
                   utils.system_id_str(protocol_packet.header.sender))
         self.neighbor = new_neighbor
         self.fsm.push_event(self.Event.NEW_NEIGHBOR)
         self.check_three_way()
         return
     # Section B.1.4.3.1
     if new_neighbor.system_id != self.neighbor.system_id:
         self.info("Neighbor system-id changed from %s to %s",
                   utils.system_id_str(self.neighbor.system_id),
                   utils.system_id_str(new_neighbor.system_id))
         self.fsm.push_event(self.Event.MULTIPLE_NEIGHBORS)
         return
     # Section B.1.4.3.2
     if new_neighbor.level != self.neighbor.level:
         self.info("Neighbor level changed from %s to %s", self.neighbor.level,
                   new_neighbor.level)
         self.fsm.push_event(self.Event.NEIGHBOR_CHANGED_LEVEL)
         return
     # Section B.1.4.3.3
     if new_neighbor.address != self.neighbor.address:
         self.info("Neighbor address changed from %s to %s", self.neighbor.address,
                   new_neighbor.address)
         self.fsm.push_event(self.Event.NEIGHBOR_CHANGED_ADDRESS)
         return
     # Section B.1.4.3.4
     if self.check_minor_change(new_neighbor):
         self.fsm.push_event(self.Event.NEIGHBOR_CHANGED_MINOR_FIELDS)
     self.neighbor = new_neighbor      # TODO: The draft does not specify this, but it is needed
     # Section B.1.4.3.5
     self.check_three_way()
예제 #4
0
 def check_reflection(self):
     # Does the received LIE packet (which is now stored in _neighbor) report us as the neighbor?
     if self.neighbor.neighbor_system_id != self._node.system_id:
         self.info("Neighbor does not report us as neighbor (system-id %s instead of %s",
                   utils.system_id_str(self.neighbor.neighbor_system_id),
                   utils.system_id_str(self._node.system_id))
         return False
     if self.neighbor.neighbor_link_id != self.local_id:
         self.info("Neighbor does not report us as neighbor (link-id %s instead of %s",
                   self.neighbor.neighbor_link_id, self.local_id)
         return False
     return True
예제 #5
0
 def cli_level_attributes(self):
     if self._running:
         return [
             self._name,
             utils.system_id_str(self._system_id), self._running,
             self._configured_level_symbol,
             self.level_value_str()
         ]
     else:
         return [
             self._name,
             utils.system_id_str(self._system_id), self._running,
             self._configured_level_symbol, '?'
         ]
예제 #6
0
 def cli_summary_attributes(self):
     if self.dest_type == DEST_TYPE_NODE:
         destination_str = utils.system_id_str(self.system_id)
         if self.name:
             destination_str += " (" + self.name + ")"
     elif self.dest_type == DEST_TYPE_PREFIX:
         destination_str = packet_common.ip_prefix_str(self.prefix)
     elif self.dest_type == DEST_TYPE_POS_DISAGG_PREFIX or \
         self.dest_type == DEST_TYPE_NEG_DISAGG_PREFIX:
         destination_str = packet_common.ip_prefix_str(self.prefix) + " (Disagg)"
     else:
         assert False
     if self.tags:
         tags_str = list(self.tags)
     else:
         tags_str = ""
     if self.positively_disaggregate:
         disaggregate_str = 'Positive'
     elif self.negatively_disaggregate:
         disaggregate_str = 'Negative'
     else:
         disaggregate_str = ''
     return [
         destination_str,
         self.cost,
         sorted(self.predecessors),
         tags_str,
         disaggregate_str,
         [str(next_hop) for next_hop in sorted(self.ipv4_next_hops)],
         [str(next_hop) for next_hop in sorted(self.ipv6_next_hops)]
     ]
예제 #7
0
def node_element_str(element):
    lines = []
    if element.name is not None:
        lines.append("Name: " + str(element.name))
    lines.append("Level: " + str(element.level))
    if element.flags is not None:
        lines.append("Flags:")
        if element.flags.overload is not None:
            lines.append("  Overload: " + str(element.flags.overload))
    if element.capabilities is not None:
        lines.append("Capabilities:")
        if element.capabilities.flood_reduction is not None:
            lines.append("  Flood reduction: " + str(element.capabilities.flood_reduction))
        if element.capabilities.hierarchy_indications is not None:
            lines.append("  Leaf indications: " +
                         hierarchy_indications_str(element.capabilities.hierarchy_indications))
    sorted_neighbors = sortedcontainers.SortedDict(element.neighbors)
    for system_id, neighbor in sorted_neighbors.items():
        lines.append("Neighbor: " + utils.system_id_str(system_id))
        lines.append("  Level: " + str(neighbor.level))
        if neighbor.cost is not None:
            lines.append("  Cost: " + str(neighbor.cost))
        if neighbor.bandwidth is not None:
            lines.append("  Bandwidth: " + bandwidth_str(neighbor.bandwidth))
        if neighbor.link_ids is not None:
            sorted_link_ids = sorted(neighbor.link_ids)
            for link_id_pair in sorted_link_ids:
                lines.append("  Link: " + link_id_pair_str(link_id_pair))
    return lines
예제 #8
0
 def cli_summary_attributes(self):
     if self._neighbor:
         return [
             self._interface_name, self._neighbor.name,
             utils.system_id_str(self._neighbor.system_id),
             self._fsm.state.name
         ]
     else:
         return [self._interface_name, "", "", self._fsm.state.name]
예제 #9
0
 def cli_summary_attributes(self):
     if self.dest_type == DEST_TYPE_NODE:
         destination_str = utils.system_id_str(self.system_id)
         if self.name:
             destination_str += " (" + self.name + ")"
     else:
         destination_str = packet_common.ip_prefix_str(self.prefix)
     if self.tags:
         tags_str = list(self.tags)
     else:
         tags_str = ""
     return [
         destination_str, self.cost,
         sorted(self.predecessors), tags_str,
         [str(next_hop) for next_hop in sorted(self.next_hops)]
     ]
예제 #10
0
 def cli_detailed_attributes(self):
     return [["Name", self._name], ["Passive", self._passive],
             ["Running", self.is_running()],
             ["System ID",
              utils.system_id_str(self._system_id)],
             ["Configured Level", self._configured_level_symbol],
             ["Leaf Only", self._leaf_only],
             ["Leaf 2 Leaf", self._leaf_2_leaf],
             ["Superspine Flag", self._superspine_flag],
             [
                 "Zero Touch Provisioning (ZTP) Enabled",
                 self.zero_touch_provisioning_enabled()
             ], ["ZTP FSM State", self._fsm.state.name],
             [
                 "ZTP Hold Down Timer",
                 self._hold_down_timer.remaining_time_str()
             ],
             [
                 "Highest Available Level (HAL)",
                 self._highest_available_level
             ],
             [
                 "Highest Adjacency Three-way (HAT)",
                 self._highest_adjacency_three_way
             ], ["Level Value", self.level_value_str()],
             [
                 "Receive LIE IPv4 Multicast Address",
                 self._rx_lie_ipv4_mcast_address
             ],
             [
                 "Transmit LIE IPv4 Multicast Address",
                 self._tx_lie_ipv4_mcast_address
             ],
             [
                 "Receive LIE IPv6 Multicast Address",
                 self._rx_lie_ipv6_mcast_address
             ],
             [
                 "Transmit LIE IPv6 Multicast Address",
                 self._tx_lie_ipv6_mcast_address
             ], ["Receive LIE Port", self._rx_lie_port],
             ["Transmit LIE Port", self._tx_lie_port],
             [
                 "LIE Send Interval",
                 "{} secs".format(self._lie_send_interval_secs)
             ], ["Receive TIE Port", self._rx_tie_port]]
예제 #11
0
 def cli_detailed_attributes(self):
     return [
         ["Interface Name", self.name],
         ["Advertised Name", self._advertised_name],
         ["Interface IPv4 Address", self._ipv4_address],
         ["Metric", self._metric],
         ["Receive LIE IPv4 Multicast Address", self._rx_lie_ipv4_mcast_address],
         ["Transmit LIE IPv4 Multicast Address", self._tx_lie_ipv4_mcast_address],
         ["Receive LIE IPv6 Multicast Address", self._rx_lie_ipv6_mcast_address],
         ["Transmit LIE IPv6 Multicast Address", self._tx_lie_ipv6_mcast_address],
         ["Receive LIE Port", self._rx_lie_port],
         ["Transmit LIE Port", self._tx_lie_port],
         ["Receive TIE Port", self._rx_tie_port],
         ["System ID", utils.system_id_str(self._node.system_id)],
         ["Local ID", self.local_id],
         ["MTU", self._mtu],
         ["POD", self._pod],
         ["Failure", self.failure_str()],
         ["State", self.state_name],
         ["Received LIE Accepted or Rejected", self._lie_accept_or_reject],
         ["Received LIE Accept or Reject Reason", self._lie_accept_or_reject_rule],
         ["Neighbor", "True" if self.neighbor else "False"]
     ]
예제 #12
0
 def cli_summary_attributes(self):
     return [
         self._name,
         utils.system_id_str(self._system_id), self._running
     ]