On Tue, Jul 24, 2018 at 08:29:30PM +0200, Björn Ketelaars wrote:
> Assuming that the pledge bits are in, the diff below enables setting of
> MTU on the interface by slaacd.
> 
> If a MTU is advertised it is checked that it is at least 1280 bytes. If
> not MTU is set to 1280. If no MTU is advertised nothing is done.
> 
> 
> diff --git sbin/slaacd/engine.c sbin/slaacd/engine.c
> index 58c39fb5c4a..762fb3af7a3 100644
> --- sbin/slaacd/engine.c
> +++ sbin/slaacd/engine.c
> @@ -164,6 +164,7 @@ struct radv {
>       LIST_HEAD(, radv_rdns)           rdns_servers;
>       uint32_t                         dnssl_lifetime;
>       LIST_HEAD(, radv_dnssl)          dnssls;
> +     uint32_t                         mtu;
>  };
>  
>  struct address_proposal {
> @@ -185,6 +186,7 @@ struct address_proposal {
>       uint32_t                         vltime;
>       uint32_t                         pltime;
>       uint8_t                          soiikey[SLAACD_SOIIKEY_LEN];
> +     uint32_t                         mtu;
>  };
>  
>  struct dfr_proposal {
> @@ -1193,6 +1195,7 @@ parse_ra(struct slaacd_iface *iface, struct imsg_ra *ra)
>               struct nd_opt_prefix_info *prf;
>               struct nd_opt_rdnss *rdnss;
>               struct nd_opt_dnssl *dnssl;
> +             struct nd_opt_mtu *mtu;
>               struct in6_addr *in6;
>               int i;
>               char *nssl;
> @@ -1293,11 +1296,23 @@ parse_ra(struct slaacd_iface *iface, struct imsg_ra 
> *ra)
>  
>                       LIST_INSERT_HEAD(&radv->dnssls, ra_dnssl, entries);
>  
> +                     break;
> +             case ND_OPT_MTU:
> +                     if (nd_opt_hdr->nd_opt_len != 1) {
> +                             log_warnx("invalid ND_OPT_MTU: len != 1");
> +                             goto err;
> +                     }
> +                     mtu = (struct nd_opt_mtu*) nd_opt_hdr;
> +                     radv->mtu = ntohl(mtu->nd_opt_mtu_mtu);
> +
> +                     /* path MTU cannot be less than IPV6_MMTU */
> +                     if (radv->mtu < IPV6_MMTU)
> +                             radv->mtu = IPV6_MMTU;

I think if we get a stupid mtu we should set no mtu, ie.

+                       if (radv->mtu < IPV6_MMTU)
+                               radv->mtu = 0;

> +
>                       break;
>               case ND_OPT_REDIRECTED_HEADER:
>               case ND_OPT_SOURCE_LINKADDR:
>               case ND_OPT_TARGET_LINKADDR:
> -             case ND_OPT_MTU:
>               case ND_OPT_ROUTE_INFO:
>  #if 0
>                       log_debug("\tOption: %u (len: %u) not implemented",
> @@ -1902,6 +1917,7 @@ configure_address(struct address_proposal 
> *addr_proposal)
>       address.vltime = addr_proposal->vltime;
>       address.pltime = addr_proposal->pltime;
>       address.privacy = addr_proposal->privacy;
> +     address.mtu = addr_proposal->mtu;
>  
>       engine_imsg_compose_main(IMSG_CONFIGURE_ADDRESS, 0, &address,
>           sizeof(address));
> @@ -1950,6 +1966,8 @@ gen_address_proposal(struct slaacd_iface *iface, struct 
> radv *ra, struct
>               addr_proposal->pltime = prefix->pltime;
>       }
>  
> +     addr_proposal->mtu = ra->mtu;
> +
>       gen_addr(iface, prefix, addr_proposal, privacy);
>  
>       tv.tv_sec = 0;
> diff --git sbin/slaacd/engine.h sbin/slaacd/engine.h
> index e7f520f1fba..4493b621b13 100644
> --- sbin/slaacd/engine.h
> +++ sbin/slaacd/engine.h
> @@ -34,6 +34,7 @@ struct imsg_configure_address {
>       struct in6_addr          mask;
>       uint32_t                 vltime;
>       uint32_t                 pltime;
> +     uint32_t                 mtu;
>       int                      privacy;
>  };
>  
> diff --git sbin/slaacd/slaacd.c sbin/slaacd/slaacd.c
> index 7afd9dc3ec7..617c6620e20 100644
> --- sbin/slaacd/slaacd.c
> +++ sbin/slaacd/slaacd.c
> @@ -761,6 +761,18 @@ configure_interface(struct imsg_configure_address 
> *address)
>  
>       if (ioctl(ioctl_sock, SIOCAIFADDR_IN6, &in6_addreq) < 0)
>               fatal("SIOCAIFADDR_IN6");
> +
> +     if (address->mtu) {
> +             struct ifreq     ifr;
> +
> +             (void) strlcpy(ifr.ifr_name, in6_addreq.ifra_name,
> +                 sizeof(ifr.ifr_name));
> +             ifr.ifr_mtu = address->mtu;
> +             log_debug("Setting MTU to %d", ifr.ifr_mtu);
> +
> +             if (ioctl(ioctl_sock, SIOCSIFMTU, &ifr) < 0)
> +                 fatal("SIOCSIFMTU");

this needs to be a log_warn, reason for this failing can be that the
hardware just can't run with the requested mtu. slaacd should keep
running in that case.

We need some mechanism to track the mtu set on the interface to not
set it over and over again. I will also need to re-read the rfc, it
has some wording on what to do in case of inconsistent mtu from
different routers.

> +     }
>  }
>  
>  void
> 

-- 
I'm not entirely sure you are real.

Reply via email to