Пример #1
0
 def lacp_handler(self, now, pkt_meta, valve, other_valves, lacp_update):
     """
     Handle receiving an LACP packet
     Args:
         now (float): current epoch time
         pkt_meta (PacketMeta): packet for control plane
         valve (Valve): valve instance
         other_valves (list): all other valves
         lacp_update: callable to signal LACP state changes
     Returns
         dict: OpenFlow messages, if any by Valve
     """
     ofmsgs_by_valve = defaultdict(list)
     if (pkt_meta.eth_dst == valve_packet.SLOW_PROTOCOL_MULTICAST
             and pkt_meta.eth_type == valve_of.ether.ETH_TYPE_SLOW
             and pkt_meta.port.lacp):
         # LACP packet so reparse
         pkt_meta.data = pkt_meta.data[:valve_packet.LACP_SIZE]
         pkt_meta.reparse_all()
         lacp_pkt = valve_packet.parse_lacp_pkt(pkt_meta.pkt)
         if lacp_pkt:
             self.logger.debug('receive LACP %s on %s' %
                               (lacp_pkt, pkt_meta.port))
             # Respond to new LACP packet or if we haven't sent anything in a while
             age = None
             if pkt_meta.port.dyn_lacp_last_resp_time:
                 age = now - pkt_meta.port.dyn_lacp_last_resp_time
             lacp_pkt_change = (
                 pkt_meta.port.dyn_last_lacp_pkt is None
                 or str(lacp_pkt) != str(pkt_meta.port.dyn_last_lacp_pkt))
             lacp_resp_interval = pkt_meta.port.lacp_resp_interval
             if lacp_pkt_change or (age is not None
                                    and age > lacp_resp_interval):
                 ofmsgs_by_valve[valve].extend(
                     self.lacp_req_reply(lacp_pkt, pkt_meta.port))
                 pkt_meta.port.dyn_lacp_last_resp_time = now
             # Update the LACP information
             actor_up = lacp_pkt.actor_state_synchronization
             ofmsgs_by_valve[valve].extend(
                 lacp_update(pkt_meta.port,
                             actor_up,
                             now=now,
                             lacp_pkt=lacp_pkt,
                             other_valves=other_valves))
             # Determine if LACP ports with the same ID have met different actor systems
             other_lag_ports = [
                 port for port in self.ports.values() if
                 port.lacp == pkt_meta.port.lacp and port.dyn_last_lacp_pkt
             ]
             actor_system = lacp_pkt.actor_system
             for other_lag_port in other_lag_ports:
                 other_actor_system = other_lag_port.dyn_last_lacp_pkt.actor_system
                 if actor_system != other_actor_system:
                     self.logger.error(
                         'LACP actor system mismatch %s: %s, %s %s' %
                         (pkt_meta.port, actor_system, other_lag_port,
                          other_actor_system))
     return ofmsgs_by_valve
Пример #2
0
    def lacp_handler(self, pkt_meta):
        """Handle a LACP packet.

        We are a currently a passive, non-aggregateable LACP partner.

        Args:
            pkt_meta (PacketMeta): packet for control plane.
        Returns:
            list: OpenFlow messages, if any.
        """
        # TODO: ensure config consistent between LAG ports.
        ofmsgs = []
        if (pkt_meta.eth_dst == valve_packet.SLOW_PROTOCOL_MULTICAST
                and pkt_meta.eth_type == valve_of.ether.ETH_TYPE_SLOW
                and pkt_meta.port.lacp):
            pkt_meta.reparse_all()
            lacp_pkt = valve_packet.parse_lacp_pkt(pkt_meta.pkt)
            if lacp_pkt:
                last_lacp_up = pkt_meta.port.dyn_lacp_up
                pkt_meta.port.dyn_last_lacp_pkt = lacp_pkt
                pkt_meta.port.dyn_lacp_up = lacp_pkt.actor_state_synchronization
                pkt_meta.port.dyn_lacp_updated_time = time.time()
                if last_lacp_up != pkt_meta.port.dyn_lacp_up:
                    self.logger.info(
                        'LACP state change from %s to %s on %s to %s LAG %u' %
                        (last_lacp_up, pkt_meta.port.dyn_lacp_up,
                         pkt_meta.port, lacp_pkt.actor_system,
                         pkt_meta.port.lacp))
                    if pkt_meta.port.dyn_lacp_up:
                        ofmsgs.extend(self.lacp_up(pkt_meta.port))
                pkt = valve_packet.lacp_reqreply(
                    pkt_meta.vlan.faucet_mac, pkt_meta.vlan.faucet_mac,
                    pkt_meta.port.lacp, pkt_meta.port.number,
                    lacp_pkt.actor_system, lacp_pkt.actor_key,
                    lacp_pkt.actor_port, lacp_pkt.actor_system_priority,
                    lacp_pkt.actor_port_priority,
                    lacp_pkt.actor_state_defaulted,
                    lacp_pkt.actor_state_expired, lacp_pkt.actor_state_timeout,
                    lacp_pkt.actor_state_collecting,
                    lacp_pkt.actor_state_distributing,
                    lacp_pkt.actor_state_aggregation,
                    lacp_pkt.actor_state_synchronization,
                    lacp_pkt.actor_state_activity)
                ofmsgs.append(
                    valve_of.packetout(pkt_meta.port.number, pkt.data))
        return ofmsgs