def ingress_packet_in_handler(self, event): msg = event.msg ofproto = self.ofproto if msg.reason == ofproto.OFPR_INVALID_TTL: LOG.debug("Get an invalid TTL packet at table %s", const.INGRESS_NAT_TABLE) if self.ingress_ttl_invalid_handler_rate_limit(): LOG.warning("Get more than %(rate)s TTL invalid " "packets per second at table %(table)s", {'rate': self.conf.dnat_ttl_invalid_max_rate, 'table': const.INGRESS_NAT_TABLE}) return icmp_ttl_pkt = icmp_error_generator.generate( icmp.ICMP_TIME_EXCEEDED, icmp.ICMP_TTL_EXPIRED_CODE, msg.data) in_port = msg.match.get('in_port') self.send_packet(in_port, icmp_ttl_pkt) return if self.ingress_icmp_error_rate_limit(): LOG.warning("Get more than %(rate)s ICMP error messages " "per second at table %(table)s", {'rate': self.conf.dnat_icmp_error_max_rate, 'table': const.INGRESS_NAT_TABLE}) return pkt = packet.Packet(msg.data) reply_pkt = self._revert_nat_for_icmp_embedded_packet(pkt, INGRESS) lport_unique_key = msg.match.get('reg7') self.dispatch_packet(reply_pkt, lport_unique_key)
def _handle_egress_invalid_ttl(self, event): LOG.debug("Get an invalid TTL packet at table %s", const.EGRESS_NAT_TABLE) if self.egress_ttl_invalid_handler_rate_limit(): LOG.warning("Get more than %(rate)s TTL invalid " "packets per second at table %(table)s", {'rate': self.conf.dnat_ttl_invalid_max_rate, 'table': const.EGRESS_NAT_TABLE}) return msg = event.msg pkt = packet.Packet(msg.data) e_pkt = pkt.get_protocol(ethernet.ethernet) port_key = msg.match.get('reg6') floatingip = self.fip_port_key_cache.get(port_key) if floatingip is None: LOG.warning("The invalid TTL packet's destination mac %s " "can't be recognized.", e_pkt.src) return icmp_ttl_pkt = icmp_error_generator.generate( icmp.ICMP_TIME_EXCEEDED, icmp.ICMP_TTL_EXPIRED_CODE, msg.data, floatingip.floating_ip_address, pkt) self.dispatch_packet(icmp_ttl_pkt, port_key)
def _handle_ttl_expired(self, msg): if self.ttl_invalid_handler_rate_limit(): LOG.warning("Get more than %(rate)s TTL invalid packets per " "second at table %(table)s", {'rate': self.conf.router_ttl_invalid_max_rate, 'table': const.L3_LOOKUP_TABLE}) return LOG.debug("Get an invalid TTL packet at table %s", const.L3_LOOKUP_TABLE) pkt = packet.Packet(msg.data) e_pkt = pkt.get_protocol(ethernet.ethernet) router_key = msg.match.get('reg5') lrouter = self.db_store.get_one( l3.LogicalRouter(unique_key=router_key), index=l3.LogicalRouter.get_index('unique_key'), ) router_port_ip = None for port in lrouter.ports: if port.lswitch.unique_key == msg.match.get('metadata'): router_port_ip = port.network.ip break if router_port_ip: icmp_ttl_pkt = icmp_error_generator.generate( icmp.ICMP_TIME_EXCEEDED, icmp.ICMP_TTL_EXPIRED_CODE, msg.data, str(router_port_ip), pkt) unique_key = msg.match.get('reg6') self.dispatch_packet(icmp_ttl_pkt, unique_key) else: LOG.warning("The invalid TTL packet's destination mac %s " "can't be recognized.", e_pkt.dst)
def _handle_invalid_dest(self, msg): """ Handle a packet sent to the router interface (by IP). Since only ping and ARP are supported, everything else is responded to with a Destination Unreachable message. :param msg: Packet in message :type msg: ryu.ofproto.ofproto_v<version>_parser.OFPPacketIn """ # If the destination is router interface, the unique key of router # interface will be set to reg7 before sending to local controller. # Code will hit here only when the router interface is not # concrete. if self.port_icmp_unreach_respond_rate_limit(): LOG.warning( "Get more than %(rate)s packets to router port " "per second at table %(table)s", { 'rate': self.conf.router_port_unreach_max_rate, 'table': const.L3_LOOKUP_TABLE }) return # Response icmp unreachable to udp or tcp. pkt = packet.Packet(msg.data) tcp_pkt = pkt.get_protocol(tcp.tcp) udp_pkt = pkt.get_protocol(udp.udp) if tcp_pkt or udp_pkt: icmp_dst_unreach = icmp_error_generator.generate( icmp.ICMP_DEST_UNREACH, icmp.ICMP_PORT_UNREACH_CODE, msg.data, pkt=pkt) unique_key = msg.match.get('reg6') self.dispatch_packet(icmp_dst_unreach, unique_key)
def _handle_ingress_invalid_ttl(self, event): LOG.debug("Get an invalid TTL packet at table %s", const.INGRESS_NAT_TABLE) if self.ingress_ttl_invalid_handler_rate_limit(): LOG.warning("Get more than %(rate)s TTL invalid " "packets per second at table %(table)s", {'rate': self.conf.dnat_ttl_invalid_max_rate, 'table': const.INGRESS_NAT_TABLE}) return msg = event.msg icmp_ttl_pkt = icmp_error_generator.generate( icmp.ICMP_TIME_EXCEEDED, icmp.ICMP_TTL_EXPIRED_CODE, msg.data) network_id = msg.match.get('metadata') self.reinject_packet( icmp_ttl_pkt, table_id=const.L2_LOOKUP_TABLE, actions=[self.parser.OFPActionSetField(metadata=network_id)] )
def egress_packet_in_handler(self, event): msg = event.msg ofproto = self.ofproto if msg.reason == ofproto.OFPR_INVALID_TTL: LOG.debug("Get an invalid TTL packet at table %s", const.EGRESS_NAT_TABLE) if self.egress_ttl_invalid_handler_rate_limit(): LOG.warning("Get more than %(rate)s TTL invalid " "packets per second at table %(table)s", {'rate': self.conf.dnat_ttl_invalid_max_rate, 'table': const.EGRESS_NAT_TABLE}) return pkt = packet.Packet(msg.data) e_pkt = pkt.get_protocol(ethernet.ethernet) mac = netaddr.EUI(e_pkt.src) floatingip = self.floatingip_rarp_cache.get(mac) if floatingip: icmp_ttl_pkt = icmp_error_generator.generate( icmp.ICMP_TIME_EXCEEDED, icmp.ICMP_TTL_EXPIRED_CODE, msg.data, floatingip, pkt) unique_key = msg.match.get('reg6') self.dispatch_packet(icmp_ttl_pkt, unique_key) else: LOG.warning("The invalid TTL packet's destination mac %s " "can't be recognized.", e_pkt.src) return if self.external_bridge_mac: if self.ingress_icmp_error_rate_limit(): LOG.warning("Get more than %(rate)s ICMP error messages " "per second at table %(table)s", {'rate': self.conf.dnat_icmp_error_max_rate, 'table': const.INGRESS_NAT_TABLE}) return pkt = packet.Packet(msg.data) reply_pkt = self._revert_nat_for_icmp_embedded_packet(pkt, EGRESS) self.send_packet(self.external_ofport, reply_pkt)
def _handle_invalid_dest(self, msg): # If the destination is router interface, the unique key of router # interface will be set to reg7 before sending to local controller. # Code will hit here only when the router interface is not # concrete. if self.port_icmp_unreach_respond_rate_limit(): LOG.warning( "Get more than %(rate)s packets to router port " "per second at table %(table)s", {'rate': self.conf.router_port_unreach_max_rate, 'table': const.L3_LOOKUP_TABLE}) return # Response icmp unreachable to udp or tcp. pkt = packet.Packet(msg.data) tcp_pkt = pkt.get_protocol(tcp.tcp) udp_pkt = pkt.get_protocol(udp.udp) if tcp_pkt or udp_pkt: icmp_dst_unreach = icmp_error_generator.generate( icmp.ICMP_DEST_UNREACH, icmp.ICMP_PORT_UNREACH_CODE, msg.data, pkt=pkt) unique_key = msg.match.get('reg6') self.dispatch_packet(icmp_dst_unreach, unique_key)
def router_function_packet_in_handler(self, msg): """React to packet as what a normal router will do. TTL invalid and router port response will be handled in this method. Return True if the packet is handled, so there is no need for further handle. """ if msg.reason == self.ofproto.OFPR_INVALID_TTL: LOG.debug("Get an invalid TTL packet at table %s", const.L3_LOOKUP_TABLE) if self.ttl_invalid_handler_rate_limit(): LOG.warning("Get more than %(rate)s TTL invalid packets per " "second at table %(table)s", {'rate': self.conf.router_ttl_invalid_max_rate, 'table': const.L3_LOOKUP_TABLE}) return True pkt = packet.Packet(msg.data) e_pkt = pkt.get_protocol(ethernet.ethernet) mac = netaddr.EUI(e_pkt.dst) router_port_ip = self.router_port_rarp_cache.get(mac) if router_port_ip: icmp_ttl_pkt = icmp_error_generator.generate( icmp.ICMP_TIME_EXCEEDED, icmp.ICMP_TTL_EXPIRED_CODE, msg.data, str(router_port_ip), pkt) unique_key = msg.match.get('reg6') self.dispatch_packet(icmp_ttl_pkt, unique_key) else: LOG.warning("The invalid TTL packet's destination mac %s " "can't be recognized.", e_pkt.dst) return True if msg.match.get('reg7'): # If the destination is router interface, the unique key of router # interface will be set to reg7 before sending to local controller. # Code will hit here only when the router interface is not # concrete. if self.port_icmp_unreach_respond_rate_limit(): LOG.warning( "Get more than %(rate)s packets to router port " "per second at table %(table)s", {'rate': self.conf.router_port_unreach_max_rate, 'table': const.L3_LOOKUP_TABLE}) return True # Response icmp unreachable to udp or tcp. pkt = packet.Packet(msg.data) tcp_pkt = pkt.get_protocol(tcp.tcp) udp_pkt = pkt.get_protocol(udp.udp) if tcp_pkt or udp_pkt: icmp_dst_unreach = icmp_error_generator.generate( icmp.ICMP_DEST_UNREACH, icmp.ICMP_PORT_UNREACH_CODE, msg.data, pkt=pkt) unique_key = msg.match.get('reg6') self.dispatch_packet(icmp_dst_unreach, unique_key) # Silently drop packet of other protocol. return True # No match in previous code. return False