[Dnsmasq-discuss] FW: Enable dnsmasq to return addresses of multiple tftp servers in cycle

Sushil Agrawal sushil.agrawal at coriolis.co.in
Tue Jun 21 15:55:34 BST 2011


[sorry if you have received multiple copies of this email; facing problems
in posting
to the list; big size etc ... ]


Attached is the modified patch after the feedback. It is also
pasted at the end of this email.

Following is the summary of the changes:

1. dnsmasq-2.57/dnsmasq.conf.
example:
2. dnsmasq-2.57/man/dnsmasq.8
    added example and description for following version of dhcp-boot

    #dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name

3.
dnsmasq-2.57/src/dnsmasq.h
    added a new field 'tftp_sname' in struct dhcp_boot
    for the tftp server name.

4.
dnsmasq-2.57/src/option.c
    added code to process the tftp_servername option.

5.
dnsmasq-2.57/src/rfc2131.c
    added code to call cache_find_by_name() to get an IP address
    of the tftp server given its name. cache_find_by_name()
    automatically returns these addresses in cycle.


tested with:

    dhcp-boot=pxelinux.0,test2,test2
in the dnsmasq.conf file

    --dhcp-boot=pxelinux.0,test2,test2
on the command line

    --dhcp-boot=pxelinux.0,,test2
on the command line.

In these examples test2 was considered as tftp server name and
so it was looked up in the cache and one ip address was returned.


Following are the diffs:

..........................................................................

diff -ru dnsmasq-2.57.origg/dnsmasq.conf.example
dnsmasq-2.57/dnsmasq.conf.example
--- dnsmasq-2.57.origg/dnsmasq.conf.example    2011-02-17 21:00:15.000000000
+0530
+++ dnsmasq-2.57/dnsmasq.conf.example    2011-06-21 18:45:45.000000000 +0530
@@ -422,6 +422,14 @@
 # Can fail with old PXE ROMS. Overridden by --pxe-service.
 #dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3

+#If there are multiple external tftp servers having a same name
+#(using /etc/hosts) then that name can be specified as the
+#tftp_servername (the third option to dhcp-boot) and in that
+#case dnsmasq resolves this name and returns the resultant IP
+#addresses in round robin fasion. This facility can be used to
+#load balance the tftp load among a set of servers.
+#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
+
 # Set the limit on DHCP leases, the default is 150
 #dhcp-lease-max=150

 #################################################################

diff -ru dnsmasq-2.57.origg/man/dnsmasq.8 dnsmasq-2.57/man/dnsmasq.8
--- dnsmasq-2.57.origg/man/dnsmasq.8    2011-02-17 21:00:15.000000000 +0530
+++ dnsmasq-2.57/man/dnsmasq.8    2011-06-21 18:47:03.000000000 +0530
@@ -845,7 +845,7 @@
 need broadcast replies set a flag in their requests so that this
 happens automatically, some old BOOTP clients do not.
 .TP
-.B \-M, --dhcp-boot=[tag:<tag>,]<filename>,[<servername>[,<server
address>]]
+.B \-M, --dhcp-boot=[tag:<tag>,]<filename>,[<servername>[,<server
address>|<tftp_servername>]]
 Set BOOTP options to be returned by the DHCP server. Server name and
 address are optional: if not provided, the name is left empty, and the
 address set to the address of the machine running dnsmasq. If dnsmasq
@@ -854,6 +854,13 @@
 ) then only the filename is required here to enable network booting.
 If the optional tag(s) are given,
 they must match for this configuration to be sent.
+If there are multiple external tftp servers having a same name
+(using /etc/hosts) then that name can be specified as the
+tftp_servername (the third option to dhcp-boot) and in that
+case dnsmasq resolves this name and returns the resultant IP
+addresses in round robin fasion. This facility can be used to
+load balance the tftp load among a set of servers.
+#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
 .TP
 .B --pxe-service=[tag:<tag>,]<CSA>,<menu
text>[,<basename>|<bootservicetype>][,<server address>]
 Most uses of PXE boot-ROMS simply allow the PXE
diff -ru dnsmasq-2.57.origg/src/dnsmasq.h dnsmasq-2.57/src/dnsmasq.h
--- dnsmasq-2.57.origg/src/dnsmasq.h    2011-02-17 21:00:15.000000000 +0530
+++ dnsmasq-2.57/src/dnsmasq.h    2011-06-21 13:59:07.000000000 +0530
@@ -519,7 +519,7 @@
 #define DHOPT_RFC3925         2048

 struct dhcp_boot {
-  char *file, *sname;
+  char *file, *sname, *tftp_sname;
   struct in_addr next_server;
   struct dhcp_netid *netid;
   struct dhcp_boot *next;
diff -ru dnsmasq-2.57.origg/src/option.c dnsmasq-2.57/src/option.c
--- dnsmasq-2.57.origg/src/option.c    2011-02-18 17:03:48.000000000 +0530
+++ dnsmasq-2.57/src/option.c    2011-06-21 16:46:31.000000000 +0530
@@ -2218,7 +2218,7 @@
       option = '?';
     else
       {
-        char *dhcp_file, *dhcp_sname = NULL;
+        char *dhcp_file, *dhcp_sname = NULL, *tftp_sname = NULL;
         struct in_addr dhcp_next_server;
         comma = split(arg);
         dhcp_file = opt_string_alloc(arg);
@@ -2231,8 +2231,17 @@
         if (comma)
           {
             unhide_metas(comma);
-            if ((dhcp_next_server.s_addr = inet_addr(comma)) ==
(in_addr_t)-1)
-              option = '?';
+            if ((dhcp_next_server.s_addr = inet_addr(comma)) ==
(in_addr_t)-1) {
+
+              /*
+               * The user may have specified the tftp hostname here.
+               * save it so that it can be resolved/looked up during
+               * actual dhcp_reply().
+               */
+
+              tftp_sname = opt_string_alloc(comma);
+              dhcp_next_server.s_addr = 0;
+            }
           }
           }
         if (option != '?')
@@ -2240,6 +2249,7 @@
         struct dhcp_boot *new = opt_malloc(sizeof(struct dhcp_boot));
         new->file = dhcp_file;
         new->sname = dhcp_sname;
+        new->tftp_sname = tftp_sname;
         new->next_server = dhcp_next_server;
         new->netid = id;
         new->next = daemon->boot_config;
diff -ru dnsmasq-2.57.origg/src/rfc2131.c dnsmasq-2.57/src/rfc2131.c
--- dnsmasq-2.57.origg/src/rfc2131.c    2011-02-17 21:00:15.000000000 +0530
+++ dnsmasq-2.57/src/rfc2131.c    2011-06-21 16:25:52.000000000 +0530
@@ -829,8 +829,23 @@
              and set discovery_control = 8 */
           if (boot)
             {
-              if (boot->next_server.s_addr)
+              if (boot->next_server.s_addr) {
             mess->siaddr = boot->next_server;
+              } else if (boot->tftp_sname) {
+
+            /*
+             * If the tftp server name is given in the conf
+             * then cycle thru its addresses.
+             */
+
+            struct crec *crecp;
+            time_t now = dnsmasq_time();
+            crecp = cache_find_by_name(NULL, boot->tftp_sname,
+                           now, F_DHCP | F_HOSTS);
+            if (crecp) {
+                mess->siaddr = *(struct in_addr*)&crecp->addr;
+            }
+              }

               if (boot->file)
             strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
@@ -2222,8 +2237,23 @@
         strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
     }

-      if (boot->next_server.s_addr)
+      if (boot->next_server.s_addr) {
     mess->siaddr = boot->next_server;
+      } else if (boot->tftp_sname) {
+
+    /*
+     * If the tftp server name is specified
+     * then cycle thru its addresses.
+     */
+
+    struct crec *crecp;
+    time_t now = dnsmasq_time();
+    crecp = cache_find_by_name(NULL, boot->tftp_sname,
+                   now, F_DHCP | F_HOSTS);
+    if (crecp) {
+        mess->siaddr = *(struct in_addr*)&crecp->addr;
+    }
+      }
     }
   else
     /* Use the values of the relevant options if no dhcp-boot given and
..........................................................................


cheers
Sushil.


On Tue, Jun 21, 2011 at 7:59 PM, Sushil Agrawal
<sushil_agrawal at hotmail.com>wrote:

>
>
> > Date: Mon, 20 Jun 2011 22:30:56 +0100
> > From: simon at thekelleys.org.uk
> > To: sushil_agrawal at hotmail.com
> > CC: dnsmasq-discuss at lists.thekelleys.org.uk
> > Subject: Re: [Dnsmasq-discuss] Enable dnsmasq to return addresses of
> multiple tftp servers in cycle
> >
> > On 19/06/11 23:00, Sushil Agrawal wrote:
> > >
> > > Sure. I'll send the man page updates.
> > >
> > > Regarding the overloading of the server name parameter:
> > > are you saying that we should have a version of the dhcp-boot option
> like:
> > >
> > > dhcp-boot=/var/ftpd/pxelinux.0,boothost,boothost
> > >
> > > and take the second 'boothost' (3rd parameter) to indicate that
> > > it be resolved and a resultant address returned as a tftp
> > > server address ?
> > >
> >
> > Exactly so. PXE doesn't use the "server name" field, but something else
> > might, (BOOTP does) so it would be nice to be able to specify if
> > independently of the TFTP server.
> >
> > In an ideal world, the order of the arguments to dhcp-boot would be
> > filename, server address, servername
> >
> > but that mistake was made long ago and were stuck with it.
> >
> >
> > Cheers,
> >
> > Simon.
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.thekelleys.org.uk/pipermail/dnsmasq-discuss/attachments/20110621/325ecfc6/attachment-0001.htm 
-------------- next part --------------
diff -ru dnsmasq-2.57.origg/dnsmasq.conf.example dnsmasq-2.57/dnsmasq.conf.example
--- dnsmasq-2.57.origg/dnsmasq.conf.example	2011-02-17 21:00:15.000000000 +0530
+++ dnsmasq-2.57/dnsmasq.conf.example	2011-06-21 18:45:45.000000000 +0530
@@ -422,6 +422,14 @@
 # Can fail with old PXE ROMS. Overridden by --pxe-service.
 #dhcp-boot=/var/ftpd/pxelinux.0,boothost,192.168.0.3
 
+#If there are multiple external tftp servers having a same name
+#(using /etc/hosts) then that name can be specified as the
+#tftp_servername (the third option to dhcp-boot) and in that
+#case dnsmasq resolves this name and returns the resultant IP
+#addresses in round robin fasion. This facility can be used to
+#load balance the tftp load among a set of servers.
+#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
+
 # Set the limit on DHCP leases, the default is 150
 #dhcp-lease-max=150
 
 #################################################################
 
diff -ru dnsmasq-2.57.origg/man/dnsmasq.8 dnsmasq-2.57/man/dnsmasq.8
--- dnsmasq-2.57.origg/man/dnsmasq.8	2011-02-17 21:00:15.000000000 +0530
+++ dnsmasq-2.57/man/dnsmasq.8	2011-06-21 18:47:03.000000000 +0530
@@ -845,7 +845,7 @@
 need broadcast replies set a flag in their requests so that this
 happens automatically, some old BOOTP clients do not.
 .TP
-.B \-M, --dhcp-boot=[tag:<tag>,]<filename>,[<servername>[,<server address>]]
+.B \-M, --dhcp-boot=[tag:<tag>,]<filename>,[<servername>[,<server address>|<tftp_servername>]]
 Set BOOTP options to be returned by the DHCP server. Server name and
 address are optional: if not provided, the name is left empty, and the
 address set to the address of the machine running dnsmasq. If dnsmasq
@@ -854,6 +854,13 @@
 ) then only the filename is required here to enable network booting.
 If the optional tag(s) are given,
 they must match for this configuration to be sent. 
+If there are multiple external tftp servers having a same name
+(using /etc/hosts) then that name can be specified as the
+tftp_servername (the third option to dhcp-boot) and in that
+case dnsmasq resolves this name and returns the resultant IP
+addresses in round robin fasion. This facility can be used to
+load balance the tftp load among a set of servers.
+#dhcp-boot=/var/ftpd/pxelinux.0,boothost,tftp_server_name
 .TP
 .B --pxe-service=[tag:<tag>,]<CSA>,<menu text>[,<basename>|<bootservicetype>][,<server address>]
 Most uses of PXE boot-ROMS simply allow the PXE
diff -ru dnsmasq-2.57.origg/src/dnsmasq.h dnsmasq-2.57/src/dnsmasq.h
--- dnsmasq-2.57.origg/src/dnsmasq.h	2011-02-17 21:00:15.000000000 +0530
+++ dnsmasq-2.57/src/dnsmasq.h	2011-06-21 13:59:07.000000000 +0530
@@ -519,7 +519,7 @@
 #define DHOPT_RFC3925         2048
 
 struct dhcp_boot {
-  char *file, *sname;
+  char *file, *sname, *tftp_sname;
   struct in_addr next_server;
   struct dhcp_netid *netid;
   struct dhcp_boot *next;
diff -ru dnsmasq-2.57.origg/src/option.c dnsmasq-2.57/src/option.c
--- dnsmasq-2.57.origg/src/option.c	2011-02-18 17:03:48.000000000 +0530
+++ dnsmasq-2.57/src/option.c	2011-06-21 16:46:31.000000000 +0530
@@ -2218,7 +2218,7 @@
 	  option = '?';
 	else 
 	  {
-	    char *dhcp_file, *dhcp_sname = NULL;
+	    char *dhcp_file, *dhcp_sname = NULL, *tftp_sname = NULL;
 	    struct in_addr dhcp_next_server;
 	    comma = split(arg);
 	    dhcp_file = opt_string_alloc(arg);
@@ -2231,8 +2231,17 @@
 		if (comma)
 		  {
 		    unhide_metas(comma);
-		    if ((dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t)-1)
-		      option = '?';
+		    if ((dhcp_next_server.s_addr = inet_addr(comma)) == (in_addr_t)-1) {
+
+		      /*
+		       * The user may have specified the tftp hostname here.
+		       * save it so that it can be resolved/looked up during
+		       * actual dhcp_reply().
+		       */	
+
+		      tftp_sname = opt_string_alloc(comma);
+		      dhcp_next_server.s_addr = 0;
+		    }
 		  }
 	      }
 	    if (option != '?')
@@ -2240,6 +2249,7 @@
 		struct dhcp_boot *new = opt_malloc(sizeof(struct dhcp_boot));
 		new->file = dhcp_file;
 		new->sname = dhcp_sname;
+		new->tftp_sname = tftp_sname;
 		new->next_server = dhcp_next_server;
 		new->netid = id;
 		new->next = daemon->boot_config;
diff -ru dnsmasq-2.57.origg/src/rfc2131.c dnsmasq-2.57/src/rfc2131.c
--- dnsmasq-2.57.origg/src/rfc2131.c	2011-02-17 21:00:15.000000000 +0530
+++ dnsmasq-2.57/src/rfc2131.c	2011-06-21 16:25:52.000000000 +0530
@@ -829,8 +829,23 @@
 		     and set discovery_control = 8 */
 		  if (boot)
 		    {
-		      if (boot->next_server.s_addr)
+		      if (boot->next_server.s_addr) {
 			mess->siaddr = boot->next_server;
+		      } else if (boot->tftp_sname) {
+
+			/*
+			 * If the tftp server name is given in the conf
+			 * then cycle thru its addresses.
+			 */
+
+			struct crec *crecp;
+			time_t now = dnsmasq_time();
+			crecp = cache_find_by_name(NULL, boot->tftp_sname,
+						   now, F_DHCP | F_HOSTS);
+			if (crecp) {
+				mess->siaddr = *(struct in_addr*)&crecp->addr;
+			}
+		      }
 		      
 		      if (boot->file)
 			strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
@@ -2222,8 +2237,23 @@
 	    strncpy((char *)mess->file, boot->file, sizeof(mess->file)-1);
 	}
       
-      if (boot->next_server.s_addr)
+      if (boot->next_server.s_addr) {
 	mess->siaddr = boot->next_server;
+      } else if (boot->tftp_sname) {
+
+	/*
+	 * If the tftp server name is specified
+	 * then cycle thru its addresses.
+	 */
+
+	struct crec *crecp;
+	time_t now = dnsmasq_time();
+	crecp = cache_find_by_name(NULL, boot->tftp_sname,
+				   now, F_DHCP | F_HOSTS);
+	if (crecp) {
+		mess->siaddr = *(struct in_addr*)&crecp->addr;
+	}
+      }
     }
   else
     /* Use the values of the relevant options if no dhcp-boot given and


More information about the Dnsmasq-discuss mailing list