diff --git a/CHANGELOG b/CHANGELOG index 7309a63..c72ab06 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -85,6 +85,9 @@ version 2.77 Add --dhcp-reply-delay option. Thanks to Floris Bos for the patch. + + Add mtu setting facility to --ra-param. Thanks to David + Flamand for the patch. version 2.76 diff --git a/man/dnsmasq.8 b/man/dnsmasq.8 index 787c104..d231e7b 100644 --- a/man/dnsmasq.8 +++ b/man/dnsmasq.8 @@ -1776,7 +1776,7 @@ the relevant link-local address of the machine running dnsmasq is sent as recursive DNS server. If provided, the DHCPv6 options dns-server and domain-search are used for the DNS server (RDNSS) and the domain search list (DNSSL). .TP -.B --ra-param=,[high|low],[[],] +.B --ra-param=,[mtu:|off,][high,|low,][,] Set non-default values for router advertisements sent via an interface. The priority field for the router may be altered from the default of medium with eg @@ -1786,8 +1786,8 @@ The interval between router advertisements may be set (in seconds) with The lifetime of the route may be changed or set to zero, which allows a router to advertise prefixes but not a route via itself. .B --ra-parm=eth0,0,0 -(A value of zero for the interval means the default value.) All three parameters may be set at once. -.B --ra-param=low,60,1200 +(A value of zero for the interval means the default value.) All four parameters may be set at once. +.B --ra-param=eth0,mtu:1280,low,60,1200 The interface field may include a wildcard. .TP .B --dhcp-reply-delay=[tag:,] diff --git a/man/fr/dnsmasq.8 b/man/fr/dnsmasq.8 index b4cc16d..080ffe3 100644 --- a/man/fr/dnsmasq.8 +++ b/man/fr/dnsmasq.8 @@ -1756,20 +1756,20 @@ dnsmasq est spécifiée comme DNS récursif. Si elles sont fournies, les options dns-server et domain-search sont utilisées respectivement pour RDNSS et DNSSL. .TP -.B --ra-param=,[high|low],[[],] +.B --ra-param=,[mtu:|off,][high,|low,][,] Configure pour une interface donnée des valeurs pour les annonces routeurs différentes des valeurs par défaut. La valeur par défaut du champ priorité pour le routeur peut-être changée de "medium" (moyen) à "high" (haute) ou "low" (basse). Par exemple : -.B --ra-param=eth0,high. +.B --ra-param=eth0,high,0. Un intervalle (en secondes) entre les annonces routeur peut-être fourni par : .B --ra-param=eth0,60. La durée de vie de la route peut-être changée ou mise à zéro, auquel cas le routeur peut annoncer les préfixes mais pas de route : .B --ra-parm=eth0,0,0 (une valeur de zéro pour l'intervalle signifie qu'il garde la valeur par défaut). -Ces trois paramètres peuvent-être configurés en une fois : -.B --ra-param=low,60,1200 +Ces quatre paramètres peuvent-être configurés en une fois : +.B --ra-param=eth0,mtu:1280,low,60,1200 La valeur pour l'interface peut inclure un caractère joker. .TP .B --enable-tftp[=[,]] diff --git a/src/dnsmasq.h b/src/dnsmasq.h index 25e4ad9..c7d9982 100644 --- a/src/dnsmasq.h +++ b/src/dnsmasq.h @@ -839,7 +839,7 @@ struct prefix_class { struct ra_interface { char *name; - int interval, lifetime, prio; + int interval, lifetime, prio, mtu; struct ra_interface *next; }; diff --git a/src/option.c b/src/option.c index 3112482..30c6d4c 100644 --- a/src/option.c +++ b/src/option.c @@ -488,7 +488,7 @@ static struct { #ifdef OPTION6_PREFIX_CLASS { LOPT_PREF_CLSS, ARG_DUP, "set:tag,", gettext_noop("Specify DHCPv6 prefix class"), NULL }, #endif - { LOPT_RA_PARAM, ARG_DUP, ",[,][,]", gettext_noop("Set priority, resend-interval and router-lifetime"), NULL }, + { LOPT_RA_PARAM, ARG_DUP, ",[mtu:|off,][,][,]", gettext_noop("Set MTU, priority, resend-interval and router-lifetime"), NULL }, { LOPT_QUIET_DHCP, OPT_QUIET_DHCP, NULL, gettext_noop("Do not log routine DHCP."), NULL }, { LOPT_QUIET_DHCP6, OPT_QUIET_DHCP6, NULL, gettext_noop("Do not log routine DHCPv6."), NULL }, { LOPT_QUIET_RA, OPT_QUIET_RA, NULL, gettext_noop("Do not log RA."), NULL }, @@ -3706,7 +3706,18 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma struct ra_interface *new = opt_malloc(sizeof(struct ra_interface)); new->lifetime = -1; new->prio = 0; + new->mtu = 0; new->name = opt_string_alloc(arg); + if (strcasestr(comma, "mtu:") == comma) + { + arg = comma + 4; + if (!(comma = split(comma))) + goto err; + if (!strcasecmp(arg, "off")) + new->mtu = -1; + else if (!atoi_check(arg, &new->mtu) || new->mtu < 1280) + goto err; + } if (strcasestr(comma, "high") == comma || strcasestr(comma, "low") == comma) { if (*comma == 'l' || *comma == 'L') @@ -3718,6 +3729,7 @@ static int one_opt(int option, char *arg, char *errstr, char *gen_err, int comma arg = split(comma); if (!atoi_check(comma, &new->interval) || (arg && !atoi_check(arg, &new->lifetime))) +err: ret_err(_("bad RA-params")); new->next = daemon->ra_interfaces; diff --git a/src/radv.c b/src/radv.c index 6cf9a66..70211c5 100644 --- a/src/radv.c +++ b/src/radv.c @@ -243,7 +243,7 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad struct dhcp_netid iface_id; struct dhcp_opt *opt_cfg; struct ra_interface *ra_param = find_iface_param(iface_name); - int done_dns = 0, old_prefix = 0; + int done_dns = 0, old_prefix = 0, mtu = 0; unsigned int min_pref_time; #ifdef HAVE_LINUX_NETWORK FILE *f; @@ -399,22 +399,31 @@ static void send_ra_alias(time_t now, int iface, char *iface_name, struct in6_ad put_opt6_long(1000 * calc_interval(find_iface_param(iface_name))); } + /* Set the MTU from ra_param if any, an MTU of 0 mean automatic for linux, */ + /* an MTU of -1 prevents the option from being sent. */ + if (ra_param) + mtu = ra_param->mtu; #ifdef HAVE_LINUX_NETWORK /* Note that IPv6 MTU is not neccessarily the same as the IPv4 MTU available from SIOCGIFMTU */ - sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", iface_name); - if ((f = fopen(daemon->namebuff, "r"))) + if (mtu == 0) { - if (fgets(daemon->namebuff, MAXDNAME, f)) - { - put_opt6_char(ICMP6_OPT_MTU); - put_opt6_char(1); - put_opt6_short(0); - put_opt6_long(atoi(daemon->namebuff)); - } - fclose(f); + sprintf(daemon->namebuff, "/proc/sys/net/ipv6/conf/%s/mtu", iface_name); + if ((f = fopen(daemon->namebuff, "r"))) + { + if (fgets(daemon->namebuff, MAXDNAME, f)) + mtu = atoi(daemon->namebuff); + fclose(f); + } } #endif + if (mtu > 0) + { + put_opt6_char(ICMP6_OPT_MTU); + put_opt6_char(1); + put_opt6_short(0); + put_opt6_long(mtu); + } iface_enumerate(AF_LOCAL, &send_iface, add_lla);