[PATCH 3/3] ip address: Add support for "valid_lft" and "preferred_lft" options

Denys Vlasenko vda.linux at googlemail.com
Fri Jul 31 16:51:54 UTC 2020


Applied, thanks!

On Mon, Jun 29, 2020 at 6:31 PM Christian Eggers <ceggers at arri.de> wrote:
>
> Signed-off-by: Christian Eggers <ceggers at arri.de>
> ---
>  networking/libiproute/ip_common.h |  4 ++
>  networking/libiproute/ipaddress.c | 65 +++++++++++++++++++++++++++----
>  2 files changed, 62 insertions(+), 7 deletions(-)
>
> diff --git a/networking/libiproute/ip_common.h b/networking/libiproute/ip_common.h
> index 40171bed9..894e380f8 100644
> --- a/networking/libiproute/ip_common.h
> +++ b/networking/libiproute/ip_common.h
> @@ -33,4 +33,8 @@ int FAST_FUNC do_iplink(char **argv);
>
>  POP_SAVED_FUNCTION_VISIBILITY
>
> +#ifndef        INFINITY_LIFE_TIME
> +#define     INFINITY_LIFE_TIME      0xFFFFFFFFU
> +#endif
> +
>  #endif
> diff --git a/networking/libiproute/ipaddress.c b/networking/libiproute/ipaddress.c
> index 6cfd3c398..71e8fb6a7 100644
> --- a/networking/libiproute/ipaddress.c
> +++ b/networking/libiproute/ipaddress.c
> @@ -592,6 +592,14 @@ int FAST_FUNC ipaddr_list_or_flush(char **argv, int flush)
>         return 0;
>  }
>
> +static void set_lifetime(unsigned int *lifetime, char *argv, const char *errmsg)
> +{
> +       if (strcmp(argv, "forever") == 0)
> +               *lifetime = INFINITY_LIFE_TIME;
> +       else
> +               *lifetime = get_u32(argv, errmsg);
> +}
> +
>  static int default_scope(inet_prefix *lcl)
>  {
>         if (lcl->family == AF_INET) {
> @@ -607,10 +615,13 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>         /* If you add stuff here, update ipaddr_full_usage */
>         static const char option[] ALIGN1 =
>                 "peer\0""remote\0""broadcast\0""brd\0"
> -               "anycast\0""scope\0""dev\0""label\0""noprefixroute\0""local\0";
> +               "anycast\0""valid_lft\0""preferred_lft\0"
> +               "scope\0""dev\0""label\0""noprefixroute\0""local\0";
>  #define option_peer      option
>  #define option_broadcast (option           + sizeof("peer") + sizeof("remote"))
>  #define option_anycast   (option_broadcast + sizeof("broadcast") + sizeof("brd"))
> +#define option_valid_lft (option_anycast   + sizeof("anycast"))
> +#define option_pref_lft  (option_valid_lft + sizeof("valid_lft"))
>         struct rtnl_handle rth;
>         struct {
>                 struct nlmsghdr  n;
> @@ -619,6 +630,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>         } req;
>         char *d = NULL;
>         char *l = NULL;
> +       char *valid_lftp = NULL;
> +       char *preferred_lftp = NULL;
>         inet_prefix lcl;
>         inet_prefix peer;
>         int local_len = 0;
> @@ -626,6 +639,8 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>         int brd_len = 0;
>         int any_len = 0;
>         bool scoped = 0;
> +       __u32 valid_lft = INFINITY_LIFE_TIME;
> +       __u32 preferred_lft = INFINITY_LIFE_TIME;
>         unsigned int ifa_flags = 0;
>
>         memset(&req, 0, sizeof(req));
> @@ -638,10 +653,9 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>         while (*argv) {
>                 unsigned arg = index_in_strings(option, *argv);
>                 /* if search fails, "local" is assumed */
> -               if ((int)arg >= 0 && arg != 8)
> -                       NEXT_ARG();
>
>                 if (arg <= 1) { /* peer, remote */
> +                       NEXT_ARG();
>                         if (peer_len) {
>                                 duparg(option_peer, *argv);
>                         }
> @@ -654,6 +668,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>                         req.ifa.ifa_prefixlen = peer.bitlen;
>                 } else if (arg <= 3) { /* broadcast, brd */
>                         inet_prefix addr;
> +                       NEXT_ARG();
>                         if (brd_len) {
>                                 duparg(option_broadcast, *argv);
>                         }
> @@ -670,6 +685,7 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>                         }
>                 } else if (arg == 4) { /* anycast */
>                         inet_prefix addr;
> +                       NEXT_ARG();
>                         if (any_len) {
>                                 duparg(option_anycast, *argv);
>                         }
> @@ -679,22 +695,39 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>                         }
>                         addattr_l(&req.n, sizeof(req), IFA_ANYCAST, &addr.data, addr.bytelen);
>                         any_len = addr.bytelen;
> -               } else if (arg == 5) { /* scope */
> +               } else if (arg == 5) { /* valid_lft */
> +                       if (valid_lftp)
> +                               duparg(option_valid_lft, *argv);
> +                       NEXT_ARG();
> +                       valid_lftp = *argv;
> +                       set_lifetime(&valid_lft, *argv, option_valid_lft);
> +               } else if (arg == 6) { /* preferred_lft */
> +                       if (preferred_lftp)
> +                               duparg(option_pref_lft, *argv);
> +                       NEXT_ARG();
> +                       preferred_lftp = *argv;
> +                       set_lifetime(&preferred_lft, *argv, option_pref_lft);
> +               } else if (arg == 7) { /* scope */
>                         uint32_t scope = 0;
> +                       NEXT_ARG();
>                         if (rtnl_rtscope_a2n(&scope, *argv)) {
>                                 invarg_1_to_2(*argv, "scope");
>                         }
>                         req.ifa.ifa_scope = scope;
>                         scoped = 1;
> -               } else if (arg == 6) { /* dev */
> +               } else if (arg == 8) { /* dev */
> +                       NEXT_ARG();
>                         d = *argv;
> -               } else if (arg == 7) { /* label */
> +               } else if (arg == 9) { /* label */
> +                       NEXT_ARG();
>                         l = *argv;
>                         addattr_l(&req.n, sizeof(req), IFA_LABEL, l, strlen(l) + 1);
> -               } else if (arg == 8) { /* noprefixroute */
> +               } else if (arg == 10) { /* noprefixroute */
>                         ifa_flags |= IFA_F_NOPREFIXROUTE;
>                 } else {
>                         /* local (specified or assumed) */
> +                       if ((int)arg >= 0)
> +                               NEXT_ARG();
>                         if (local_len) {
>                                 duparg2("local", *argv);
>                         }
> @@ -755,6 +788,24 @@ static int ipaddr_modify(int cmd, int flags, char **argv)
>
>         req.ifa.ifa_index = xll_name_to_index(d);
>
> +       if (valid_lftp || preferred_lftp) {
> +               struct ifa_cacheinfo cinfo = {};
> +
> +               if (!valid_lft) {
> +                       fprintf(stderr, "valid_lft is zero\n");
> +                       return 1;
> +               }
> +               if (valid_lft < preferred_lft) {
> +                       fprintf(stderr, "preferred_lft is greater than valid_lft\n");
> +                       return 1;
> +               }
> +
> +               cinfo.ifa_prefered = preferred_lft;
> +               cinfo.ifa_valid = valid_lft;
> +               addattr_l(&req.n, sizeof(req), IFA_CACHEINFO, &cinfo,
> +                         sizeof(cinfo));
> +       }
> +
>         if (rtnl_talk(&rth, &req.n, 0, 0, NULL, NULL, NULL) < 0)
>                 return 2;
>
> --
> Christian Eggers
> Embedded software developer
>
> Arnold & Richter Cine Technik GmbH & Co. Betriebs KG
> Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRA 57918
> Persoenlich haftender Gesellschafter: Arnold & Richter Cine Technik GmbH
> Sitz: Muenchen - Registergericht: Amtsgericht Muenchen - Handelsregisternummer: HRB 54477
> Geschaeftsfuehrer: Dr. Michael Neuhaeuser; Stephan Schenk; Walter Trauninger; Markus Zeiler
>
> _______________________________________________
> busybox mailing list
> busybox at busybox.net
> http://lists.busybox.net/mailman/listinfo/busybox


More information about the busybox mailing list