Revision 764f829a nfdhcpd

b/nfdhcpd
122 122
def get_indev(payload):
123 123
    try:
124 124
        indev_ifindex = payload.get_physindev()
125
        logging.debug("get_physindev %s", indev_ifindex)
126 125
        if indev_ifindex:
127 126
            logging.debug("Incomming packet from bridge %s", indev_ifindex)
128 127
            return indev_ifindex
......
136 135

  
137 136
    return indev_ifindex
138 137

  
138

  
139 139
def get_binding(proxy, ifindex, mac):
140 140
    try:
141 141
        if proxy.mac_indexed_clients:
142
            logging.debug("get_binding for mac %s", mac)
142
            logging.debug("Getting binding for mac %s", mac)
143 143
            b = proxy.clients[mac]
144 144
        else:
145
            logging.debug("get_binding for ifindex %s", ifindex)
145
            logging.debug("Getting binding for ifindex %s", ifindex)
146 146
            b = proxy.clients[ifindex]
147 147
        return b
148 148
    except KeyError:
149 149
        logging.debug("No client found for mac/ifindex %s/%s", mac, ifindex)
150 150
        return None
151 151

  
152

  
152 153
def parse_binding_file(path):
153 154
    """ Read a client configuration from a tap file
154 155

  
155 156
    """
157
    logging.info("Parsing binding file %s", path)
156 158
    try:
157 159
        iffile = open(path, 'r')
158 160
    except EnvironmentError, e:
......
173 175
    def get_value(line):
174 176
        v = line.strip().split('=')[1]
175 177
        if v == '':
176
          return None
178
            return None
177 179
        return v
178 180

  
179 181
    for line in iffile:
......
204 206
    except:
205 207
        return None
206 208

  
209

  
207 210
class ClientFileHandler(pyinotify.ProcessEvent):
208 211
    def __init__(self, server):
209 212
        pyinotify.ProcessEvent.__init__(self)
210 213
        self.server = server
211 214

  
212
    def process_IN_DELETE(self, event): # pylint: disable=C0103
215
    def process_IN_DELETE(self, event):  # pylint: disable=C0103
213 216
        """ Delete file handler
214 217

  
215 218
        Currently this removes an interface from the watch list
......
217 220
        """
218 221
        self.server.remove_tap(event.name)
219 222

  
220
    def process_IN_CLOSE_WRITE(self, event): # pylint: disable=C0103
223
    def process_IN_CLOSE_WRITE(self, event):  # pylint: disable=C0103
221 224
        """ Add file handler
222 225

  
223 226
        Currently this adds an interface to the watch list
......
316 319
        return self._make_eui64("fe80::", mac)
317 320

  
318 321

  
319
class VMNetProxy(object): # pylint: disable=R0902
320
    def __init__(self, data_path, dhcp_queue_num=None, # pylint: disable=R0913
322
class VMNetProxy(object):  # pylint: disable=R0902
323
    def __init__(self, data_path, dhcp_queue_num=None,  # pylint: disable=R0913
321 324
                 rs_queue_num=None, ns_queue_num=None,
322 325
                 dhcp_lease_lifetime=DEFAULT_LEASE_LIFETIME,
323 326
                 dhcp_lease_renewal=DEFAULT_LEASE_RENEWAL,
......
396 399
        logging.info("Cleanup finished")
397 400

  
398 401
    def _setup_nfqueue(self, queue_num, family, callback):
399
        logging.debug("Setting up NFQUEUE for queue %d, AF %s",
402
        logging.info("Setting up NFQUEUE for queue %d, AF %s",
400 403
                      queue_num, family)
401 404
        q = nfqueue.queue()
402 405
        q.set_callback(callback)
......
405 408
        # This is mandatory for the queue to operate
406 409
        q.set_mode(nfqueue.NFQNL_COPY_PACKET)
407 410
        self.nfq[q.get_fd()] = q
411
        logging.debug("Successfully set up NFQUEUE %d", queue_num)
408 412

  
409 413
    def sendp(self, data, dev):
410 414
        """ Send a raw packet using a layer-2 socket
411 415

  
412 416
        """
413
        logging.debug("%s", data)
417
        logging.debug("Sending raw packet %s", data)
414 418
        if isinstance(data, BasePacket):
415 419
            data = str(data)
416 420

  
......
427 431
        for path in glob.glob(os.path.join(self.data_path, "*")):
428 432
            self.add_tap(path)
429 433

  
430
        logging.debug("\n\n\n\n\n")
431
        logging.debug("%10s %20s %7s %15s", 'Client', 'MAC', 'TAP', 'IP')
434
        logging.debug("%15s %20s %7s %15s", 'Client', 'MAC', 'TAP', 'IP')
432 435
        for b in self.clients.values():
433
            logging.debug("%10s %20s %7s %15s", b.hostname, b.mac, b.tap, b.ip)
436
            logging.debug("%15s %20s %7s %15s", b.hostname, b.mac, b.tap, b.ip)
434 437

  
435 438
    def get_ifindex(self, iface):
436 439
        """ Get the interface index from sysfs
437 440

  
438 441
        """
442
        logging.debug("Getting ifindex for interface %s from sysfs", iface)
443

  
439 444
        path = os.path.abspath(os.path.join(SYSFS_NET, iface, "ifindex"))
440 445
        if not path.startswith(SYSFS_NET):
441 446
            return None
......
466 471

  
467 472
        return ifindex
468 473

  
469

  
470 474
    def get_iface_hw_addr(self, iface):
471 475
        """ Get the interface hardware address from sysfs
472 476

  
473 477
        """
478
        logging.debug("Getting mac for iface %s", iface)
474 479
        path = os.path.abspath(os.path.join(SYSFS_NET, iface, "address"))
475 480
        if not path.startswith(SYSFS_NET):
476 481
            return None
......
532 537
        except:
533 538
            logging.debug("Client on %s disappeared!!!", tap)
534 539

  
535

  
536
    def dhcp_response(self, i, payload): # pylint: disable=W0613,R0914
540
    def dhcp_response(self, i, payload):  # pylint: disable=W0613,R0914
537 541
        """ Generate a reply to bnetfilter-queue-deva BOOTP/DHCP request
538 542

  
539 543
        """
......
546 550
        resp = pkt.getlayer(BOOTP).copy()
547 551
        hlen = resp.hlen
548 552
        mac = resp.chaddr[:hlen].encode("hex")
549
        mac, _ = re.subn(r'([0-9a-fA-F]{2})', r'\1:', mac, hlen-1)
553
        mac, _ = re.subn(r'([0-9a-fA-F]{2})', r'\1:', mac, hlen - 1)
550 554

  
551 555
        # Server responses are always BOOTREPLYs
552 556
        resp.op = "BOOTREPLY"
......
564 568
            payload.set_verdict(nfqueue.NF_ACCEPT)
565 569
            return
566 570

  
567

  
568 571
        # Signal the kernel that it shouldn't further process the packet
569 572
        payload.set_verdict(nfqueue.NF_DROP)
570 573

  
......
616 619
                 ("lease_time", self.lease_lifetime),
617 620
            ]
618 621
            if subnet.gw:
619
              dhcp_options += [("router", subnet.gw)]
622
                dhcp_options += [("router", subnet.gw)]
620 623
            dhcp_options += [("name_server", x) for x in self.dhcp_nameservers]
621 624

  
622 625
        elif req_type == DHCPINFORM:
......
629 632

  
630 633
        elif req_type == DHCPRELEASE:
631 634
            # Log and ignore
632
            logging.info("DHCPRELEASE from %s on %s", binding.mac, binding.tap )
635
            logging.info("DHCPRELEASE from %s on %s", binding.mac, binding.tap)
633 636
            return
634 637

  
635 638
        # Finally, always add the server identifier and end options
......
650 653
            logging.warn("Unkown error during DHCP response on %s: %s",
651 654
                         binding.indev, str(e))
652 655

  
653
    def rs_response(self, i, payload): # pylint: disable=W0613
656
    def rs_response(self, i, payload):  # pylint: disable=W0613
654 657
        """ Generate a reply to a BOOTP/DHCP request
655 658

  
656 659
        """
660

  
657 661
        pkt = IPv6(payload.get_data())
658
        logging.debug("IN RS RESPONCE")
659 662
        #logging.debug(pkt.show())
660 663
        try:
661 664
            mac = pkt.lladdr
......
663 666
            logging.debug("Cannot obtain lladdr in rs")
664 667
            return
665 668

  
666
        logging.debug("rs for mac %s", mac)
669
        logging.debug("Generating an rs response for mac %s", mac)
667 670

  
668 671
        indev = get_indev(payload)
669 672

  
......
687 690
        subnet = binding.net6
688 691

  
689 692
        if subnet.net is None:
690
          logging.debug("No IPv6 network assigned for the interface")
691
          return
693
            logging.debug("No IPv6 network assigned for the interface")
694
            return
692 695

  
693 696
        indevmac = self.get_iface_hw_addr(binding.indev)
694 697
        ifll = subnet.make_ll64(indevmac)
695 698
        if ifll is None:
696 699
            return
697 700

  
698

  
699 701
        resp = Ether(src=indevmac)/\
700 702
               IPv6(src=str(ifll))/ICMPv6ND_RA(routerlifetime=14400)/\
701 703
               ICMPv6NDOptPrefixInfo(prefix=str(subnet.prefix),
......
714 716
            logging.warn("Unkown error during RA on %s: %s",
715 717
                         binding.indev, str(e))
716 718

  
717
    def ns_response(self, i, payload): # pylint: disable=W0613
719
    def ns_response(self, i, payload):  # pylint: disable=W0613
718 720
        """ Generate a reply to an ICMPv6 neighbor solicitation
719 721

  
720 722
        """
723

  
721 724
        ns = IPv6(payload.get_data())
722
        logging.debug("IN NS RESPONCE")
723 725
        #logging.debug(ns.show())
724 726
        try:
725 727
            mac = ns.lladdr
......
727 729
            logging.debug("Cannot obtain lladdr from ns")
728 730
            return
729 731

  
730
        logging.debug("dst %s  tgt %s" , ns.dst, ns.tgt)
732
        logging.debug("Generating ns response, dst: %s  tgt: %s", ns.dst, ns.tgt)
731 733

  
732 734
        indev = get_indev(payload)
733 735

  
......
749 751

  
750 752
        subnet = binding.net6
751 753
        if subnet.net is None:
752
          logging.debug("No IPv6 network assigned for the interface")
753
          return
754
            logging.debug("No IPv6 network assigned for the interface")
755
            return
754 756

  
755 757
        indevmac = self.get_iface_hw_addr(binding.indev)
756 758

  
......
790 792
        for binding in self.clients.values():
791 793
            tap = binding.tap
792 794
            indev = binding.indev
793
            mac = binding.mac
795
            # mac = binding.mac
794 796
            subnet = binding.net6
795 797
            if subnet.net is None:
796 798
                logging.debug("Skipping periodic RA on interface %s,"
......
834 836

  
835 837
        # Yes, we are accessing _fd directly, but it's the only way to have a
836 838
        # single select() loop ;-)
837
        iwfd = self.notifier._fd # pylint: disable=W0212
839
        iwfd = self.notifier._fd  # pylint: disable=W0212
838 840

  
839 841
        start = time.time()
840 842
        if self.ipv6_enabled:
......
847 849
            rlist, _, xlist = select(self.nfq.keys() + [iwfd], [], [], timeout)
848 850
            if xlist:
849 851
                logging.warn("Warning: Exception on %s",
850
                             ", ".join([ str(fd) for fd in xlist]))
852
                             ", ".join([str(fd) for fd in xlist]))
851 853

  
852 854
            if rlist:
853 855
                if iwfd in rlist:
......
910 912
    validator.functions["ip_addr_list"] = is_ip_list
911 913
    config_spec = StringIO(CONFIG_SPEC)
912 914

  
913

  
914 915
    parser = optparse.OptionParser()
915 916
    parser.add_option("-c", "--config", dest="config_file",
916 917
                      help="The location of the data files", metavar="FILE",
......
921 922
                      dest="daemonize", default=True,
922 923
                      help="Do not daemonize, stay in the foreground")
923 924

  
924

  
925 925
    opts, args = parser.parse_args()
926 926

  
927 927
    try:
......
1017 1017
    # CAP_NET_ADMIN: we need to send nfqueue packet verdicts to a netlinkgroup
1018 1018
    capng.capng_clear(capng.CAPNG_SELECT_BOTH)
1019 1019
    capng.capng_update(capng.CAPNG_ADD,
1020
                       capng.CAPNG_EFFECTIVE|capng.CAPNG_PERMITTED,
1020
                       capng.CAPNG_EFFECTIVE | capng.CAPNG_PERMITTED,
1021 1021
                       capng.CAP_NET_ADMIN)
1022 1022
    capng.capng_change_id(uid.pw_uid, uid.pw_gid,
1023
                          capng.CAPNG_DROP_SUPP_GRP|capng.CAPNG_CLEAR_BOUNDING)
1023
                          capng.CAPNG_DROP_SUPP_GRP | capng.CAPNG_CLEAR_BOUNDING)
1024 1024

  
1025 1025
    logging.info("Ready to serve requests")
1026 1026
    try:

Also available in: Unified diff