Example #1
0
    def test_default_args(self):
        ig = igmp()
        buf = ig.serialize(bytearray(), None)
        res = unpack_from(igmp._PACK_STR, str(buf))

        eq_(res[0], 0x11)
        eq_(res[1], 0)
        eq_(res[3], addrconv.ipv4.text_to_bin('0.0.0.0'))
Example #2
0
    def test_default_args(self):
        ig = igmp()
        buf = ig.serialize(bytearray(), None)
        res = unpack_from(igmp._PACK_STR, six.binary_type(buf))

        eq_(res[0], 0x11)
        eq_(res[1], 0)
        eq_(res[3], addrconv.ipv4.text_to_bin('0.0.0.0'))
Example #3
0
    def setUp(self):
        self.msgtype = IGMP_TYPE_QUERY
        self.maxresp = 100
        self.csum = 0
        self.address = "225.0.0.1"

        self.buf = pack(igmp._PACK_STR, self.msgtype, self.maxresp, self.csum, addrconv.ipv4.text_to_bin(self.address))

        self.g = igmp(self.msgtype, self.maxresp, self.csum, self.address)
Example #4
0
    def setUp(self):
        self.msgtype = IGMP_TYPE_QUERY
        self.maxresp = 100
        self.csum = 0
        self.address = '225.0.0.1'

        self.buf = pack(igmp._PACK_STR, self.msgtype, self.maxresp, self.csum,
                        addrconv.ipv4.text_to_bin(self.address))

        self.g = igmp(self.msgtype, self.maxresp, self.csum, self.address)
Example #5
0
    def _do_leave(self, leave, in_port, msg):
        """the process when the snooper received a LEAVE message."""
        datapath = msg.datapath
        dpid = datapath.id
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # check whether the querier port has been specified.
        if not self._to_querier.get(dpid):
            self.logger.info("no querier exists.")
            return

        # save this LEAVE message and reset the condition of the port
        # that received this message.
        self._to_hosts.setdefault(dpid, {})
        self._to_hosts[dpid].setdefault(leave.address, {
            'replied': False,
            'leave': None,
            'ports': {}
        })
        self._to_hosts[dpid][leave.address]['leave'] = msg
        self._to_hosts[dpid][leave.address]['ports'][in_port] = {
            'out': False,
            'in': False
        }

        # create a specific query.
        timeout = igmp.LAST_MEMBER_QUERY_INTERVAL
        res_igmp = igmp.igmp(msgtype=igmp.IGMP_TYPE_QUERY,
                             maxresp=timeout * 10,
                             csum=0,
                             address=leave.address)
        res_ipv4 = ipv4.ipv4(total_length=len(ipv4.ipv4()) + len(res_igmp),
                             proto=inet.IPPROTO_IGMP,
                             ttl=1,
                             src=self._to_querier[dpid]['ip'],
                             dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(dst=igmp.MULTICAST_MAC_ALL_HOST,
                                      src=self._to_querier[dpid]['mac'],
                                      ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        # send a specific query to the host that sent this message.
        actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
        self._do_packet_out(datapath, res_pkt.data, in_port, actions)

        # wait for REPORT messages.
        hub.spawn(self._do_timeout_for_leave, timeout, datapath, leave.address,
                  in_port)
Example #6
0
    def _do_leave(self, leave, in_port, msg):
        """the process when the snooper received a LEAVE message."""
        datapath = msg.datapath
        dpid = datapath.id
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        # check whether the querier port has been specified.
        if not self._to_querier.get(dpid):
            self.logger.info("no querier exists.")
            return

        # save this LEAVE message and reset the condition of the port
        # that received this message.
        self._to_hosts.setdefault(dpid, {})
        self._to_hosts[dpid].setdefault(
            leave.address,
            {'replied': False, 'leave': None, 'ports': {}})
        self._to_hosts[dpid][leave.address]['leave'] = msg
        self._to_hosts[dpid][leave.address]['ports'][in_port] = {
            'out': False, 'in': False}

        # create a specific query.
        timeout = igmp.LAST_MEMBER_QUERY_INTERVAL
        res_igmp = igmp.igmp(
            msgtype=igmp.IGMP_TYPE_QUERY,
            maxresp=timeout * 10,
            csum=0,
            address=leave.address)
        res_ipv4 = ipv4.ipv4(
            total_length=len(ipv4.ipv4()) + len(res_igmp),
            proto=inet.IPPROTO_IGMP, ttl=1,
            src=self._to_querier[dpid]['ip'],
            dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(
            dst=igmp.MULTICAST_MAC_ALL_HOST,
            src=self._to_querier[dpid]['mac'],
            ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        # send a specific query to the host that sent this message.
        actions = [parser.OFPActionOutput(ofproto.OFPP_IN_PORT)]
        self._do_packet_out(datapath, res_pkt.data, in_port, actions)

        # wait for REPORT messages.
        hub.spawn(self._do_timeout_for_leave, timeout, datapath,
                  leave.address, in_port)
Example #7
0
    def _querying_thread(self):
        """ send a QUERY message periodically."""

        # delay 5 seconds before sending out the first
        hub.sleep(5)

        dp = self.dp
        ofproto = dp.ofproto
        parser = dp.ofproto_parser

        # create a general query.
        res_igmp = igmp.igmp(msgtype=igmp.IGMP_TYPE_QUERY,
                             maxresp=igmp.QUERY_RESPONSE_INTERVAL * 10,
                             csum=0,
                             address='0.0.0.0')
        res_ipv4 = ipv4.ipv4(total_length=len(ipv4.ipv4()) + len(res_igmp),
                             proto=inet.IPPROTO_IGMP,
                             ttl=1,
                             src='0.0.0.0',
                             dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(dst=igmp.MULTICAST_MAC_ALL_HOST,
                                      src=dp.ports[ofproto.OFPP_LOCAL].hw_addr,
                                      ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        #query_ports = [parser.OFPActionOutput(port) for port in self.reg_ports]
        query_ports = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]

        while True:
            # send a general query to the host that sent this message.
            out = parser.OFPPacketOut(datapath=dp,
                                      buffer_id=ofproto.OFP_NO_BUFFER,
                                      data=res_pkt,
                                      in_port=ofproto.OFPP_LOCAL,
                                      actions=query_ports)
            dp.send_msg(out)
            self.logger.debug("dp %s, igmp query sent" % dp.id)
            hub.sleep(QueryInterval)
Example #8
0
    def _send_query(self):
        """ send a QUERY message periodically."""
        timeout = 60
        datapath = self._dpid_to_datapath.get(self._querier)
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser
        if ofproto_v1_0.OFP_VERSION == ofproto.OFP_VERSION:
            send_port = ofproto.OFPP_NONE
        else:
            send_port = ofproto.OFPP_ANY

        # create a general query.
        res_igmp = igmp.igmp(
            msgtype=igmp.IGMP_TYPE_QUERY,
            maxresp=igmp.QUERY_RESPONSE_INTERVAL * 10,
            csum=0,
            address='0.0.0.0')
        res_ipv4 = ipv4.ipv4(
            total_length=len(ipv4.ipv4()) + len(res_igmp),
            proto=inet.IPPROTO_IGMP, ttl=1,
            src='0.0.0.0',
            dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(
            dst=igmp.MULTICAST_MAC_ALL_HOST,
            src=datapath.ports[ofproto.OFPP_LOCAL].hw_addr,
            ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        flood = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]

        while True:
            # send a general query to the host that sent this message.
            self._do_packet_out(
                datapath, res_pkt.data, send_port, flood)
            hub.sleep(igmp.QUERY_RESPONSE_INTERVAL)
            rest_time = timeout - igmp.QUERY_RESPONSE_INTERVAL
            hub.sleep(rest_time)
Example #9
0
    def _send_query(self):
        """ send a QUERY message periodically."""
        timeout = 60
        ofproto = self._datapath.ofproto
        parser = self._datapath.ofproto_parser
        if ofproto_v1_0.OFP_VERSION == ofproto.OFP_VERSION:
            send_port = ofproto.OFPP_NONE
        else:
            send_port = ofproto.OFPP_ANY

        # create a general query.
        res_igmp = igmp.igmp(
            msgtype=igmp.IGMP_TYPE_QUERY,
            maxresp=igmp.QUERY_RESPONSE_INTERVAL * 10,
            csum=0,
            address='0.0.0.0')
        res_ipv4 = ipv4.ipv4(
            total_length=len(ipv4.ipv4()) + len(res_igmp),
            proto=inet.IPPROTO_IGMP, ttl=1,
            src='0.0.0.0',
            dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(
            dst=igmp.MULTICAST_MAC_ALL_HOST,
            src=self._datapath.ports[ofproto.OFPP_LOCAL].hw_addr,
            ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        flood = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]

        while True:
            # reset reply status.
            for status in self._mcast.values():
                for port in status.keys():
                    status[port] = False

            # send a general query to the host that sent this message.
            self._do_packet_out(
                self._datapath, res_pkt.data, send_port, flood)
            hub.sleep(igmp.QUERY_RESPONSE_INTERVAL)

            # QUERY timeout expired.
            del_groups = []
            for group, status in self._mcast.items():
                del_ports = []
                actions = []
                for port in status.keys():
                    if not status[port]:
                        del_ports.append(port)
                    else:
                        actions.append(parser.OFPActionOutput(port))
                if len(actions) and len(del_ports):
                    self._set_flow_entry(
                        self._datapath, actions, self.server_port, group)
                if not len(actions):
                    self._del_flow_entry(
                        self._datapath, self.server_port, group)
                    del_groups.append(group)
                if len(del_ports):
                    for port in del_ports:
                        self._del_flow_entry(self._datapath, port, group)
                for port in del_ports:
                    del status[port]
            for group in del_groups:
                del self._mcast[group]

            rest_time = timeout - igmp.QUERY_RESPONSE_INTERVAL
            hub.sleep(rest_time)
Example #10
0
    def _send_query(self):
        """ send a QUERY message periodically."""
        timeout = 60
        ofproto = self._datapath.ofproto
        parser = self._datapath.ofproto_parser
        if ofproto_v1_0.OFP_VERSION == ofproto.OFP_VERSION:
            send_port = ofproto.OFPP_NONE
        else:
            send_port = ofproto.OFPP_ANY

        # create a general query.
        res_igmp = igmp.igmp(msgtype=igmp.IGMP_TYPE_QUERY,
                             maxresp=igmp.QUERY_RESPONSE_INTERVAL * 10,
                             csum=0,
                             address='0.0.0.0')
        res_ipv4 = ipv4.ipv4(total_length=len(ipv4.ipv4()) + len(res_igmp),
                             proto=inet.IPPROTO_IGMP,
                             ttl=1,
                             src='0.0.0.0',
                             dst=igmp.MULTICAST_IP_ALL_HOST)
        res_ether = ethernet.ethernet(
            dst=igmp.MULTICAST_MAC_ALL_HOST,
            src=self._datapath.ports[ofproto.OFPP_LOCAL].hw_addr,
            ethertype=ether.ETH_TYPE_IP)
        res_pkt = packet.Packet()
        res_pkt.add_protocol(res_ether)
        res_pkt.add_protocol(res_ipv4)
        res_pkt.add_protocol(res_igmp)
        res_pkt.serialize()

        flood = [parser.OFPActionOutput(ofproto.OFPP_FLOOD)]

        while True:
            # reset reply status.
            for status in self._mcast.values():
                for port in status.keys():
                    status[port] = False

            # send a general query to the host that sent this message.
            self._do_packet_out(self._datapath, res_pkt.data, send_port, flood)
            hub.sleep(igmp.QUERY_RESPONSE_INTERVAL)

            # QUERY timeout expired.
            del_groups = []
            for group, status in self._mcast.items():
                del_ports = []
                actions = []
                for port in status.keys():
                    if not status[port]:
                        del_ports.append(port)
                    else:
                        actions.append(parser.OFPActionOutput(port))
                if len(actions) and len(del_ports):
                    self._set_flow_entry(self._datapath, actions,
                                         self.server_port, group)
                if not len(actions):
                    self._del_flow_entry(self._datapath, self.server_port,
                                         group)
                    del_groups.append(group)
                if len(del_ports):
                    for port in del_ports:
                        self._del_flow_entry(self._datapath, port, group)
                for port in del_ports:
                    del status[port]
            for group in del_groups:
                del self._mcast[group]

            rest_time = timeout - igmp.QUERY_RESPONSE_INTERVAL
            hub.sleep(rest_time)