]> git.ipfire.org Git - thirdparty/iproute2.git/commitdiff
Merge git://git.kernel.org/pub/scm/network/iproute2/iproute2-next
authorStephen Hemminger <stephen@networkplumber.org>
Wed, 28 Apr 2021 02:39:39 +0000 (19:39 -0700)
committerStephen Hemminger <stephen@networkplumber.org>
Wed, 28 Apr 2021 02:39:39 +0000 (19:39 -0700)
Required manual fix of devlink/devlink.c

Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
1  2 
devlink/devlink.c
ip/ip.c
ip/ipnexthop.c

index faa87b3def678613c1a9270ea2a510faf23b8951,16eca4f9eed926716c09fc6bff4e7246128002ad..0b5548fbee98344b9d16dcfb926c0a8d1cb32c0a
@@@ -965,13 -917,7 +917,13 @@@ static int strtobool(const char *str, b
  
  static int __dl_argv_handle(char *str, char **p_bus_name, char **p_dev_name)
  {
 -      str_split_by_char(str, p_bus_name, p_dev_name, '/');
 +      int err;
 +
-       err = strslashrsplit(str, p_bus_name, p_dev_name);
++      err = str_split_by_char(str, p_bus_name, p_dev_name, '/');
 +      if (err) {
 +              pr_err("Devlink identification (\"bus_name/dev_name\") \"%s\" is invalid\n", str);
 +              return err;
 +      }
        return 0;
  }
  
diff --cc ip/ip.c
Simple merge
diff --cc ip/ipnexthop.c
index f0658a9cbc4d459a3e6901c5d980a859e55d69e7,e88feaf6afe7eb3447673a110d348a2a454a204f..9478aa5298eb149ad44de35b5ac8b6ac494c0ed1
@@@ -275,11 -408,54 +408,55 @@@ int print_nexthop(struct nlmsghdr *n, v
        return 0;
  }
  
+ int print_nexthop_bucket(struct nlmsghdr *n, void *arg)
+ {
+       struct nhmsg *nhm = NLMSG_DATA(n);
+       struct rtattr *tb[NHA_MAX+1];
+       FILE *fp = (FILE *)arg;
+       int len;
+       if (n->nlmsg_type != RTM_DELNEXTHOPBUCKET &&
+           n->nlmsg_type != RTM_NEWNEXTHOPBUCKET) {
+               fprintf(stderr, "Not a nexthop bucket: %08x %08x %08x\n",
+                       n->nlmsg_len, n->nlmsg_type, n->nlmsg_flags);
+               return -1;
+       }
+       len = n->nlmsg_len - NLMSG_SPACE(sizeof(*nhm));
+       if (len < 0) {
+               close_json_object();
+               fprintf(stderr, "BUG: wrong nlmsg len %d\n", len);
+               return -1;
+       }
+       parse_rtattr_flags(tb, NHA_MAX, RTM_NHA(nhm), len, NLA_F_NESTED);
+       open_json_object(NULL);
+       if (n->nlmsg_type == RTM_DELNEXTHOP)
+               print_bool(PRINT_ANY, "deleted", "Deleted ", true);
+       if (tb[NHA_ID])
+               print_uint(PRINT_ANY, "id", "id %u ",
+                          rta_getattr_u32(tb[NHA_ID]));
+       if (tb[NHA_RES_BUCKET])
+               print_nh_res_bucket(fp, tb[NHA_RES_BUCKET]);
+       print_rt_flags(fp, nhm->nh_flags);
+       print_string(PRINT_FP, NULL, "%s", "\n");
+       close_json_object();
+       fflush(fp);
+       return 0;
+ }
  static int add_nh_group_attr(struct nlmsghdr *n, int maxlen, char *argv)
  {
 -      struct nexthop_grp *grps;
 +      struct nexthop_grp *grps = NULL;
        int count = 0, i;
 +      int err = -1;
        char *sep, *wsep;
  
        if (*argv != '\0')
                argv = sep + 1;
        }
  
 -      return addattr_l(n, maxlen, NHA_GROUP, grps, count * sizeof(*grps));
 +      err = addattr_l(n, maxlen, NHA_GROUP, grps, count * sizeof(*grps));
 +out:
 +      free(grps);
 +      return err;
  }
  
+ static int read_nh_group_type(const char *name)
+ {
+       if (strcmp(name, "mpath") == 0)
+               return NEXTHOP_GRP_TYPE_MPATH;
+       else if (strcmp(name, "resilient") == 0)
+               return NEXTHOP_GRP_TYPE_RES;
+       return __NEXTHOP_GRP_TYPE_MAX;
+ }
+ static void parse_nh_group_type_res(struct nlmsghdr *n, int maxlen, int *argcp,
+                                   char ***argvp)
+ {
+       char **argv = *argvp;
+       struct rtattr *nest;
+       int argc = *argcp;
+       if (!NEXT_ARG_OK())
+               return;
+       nest = addattr_nest(n, maxlen, NHA_RES_GROUP);
+       nest->rta_type |= NLA_F_NESTED;
+       NEXT_ARG_FWD();
+       while (argc > 0) {
+               if (strcmp(*argv, "buckets") == 0) {
+                       __u16 buckets;
+                       NEXT_ARG();
+                       if (get_u16(&buckets, *argv, 0))
+                               invarg("invalid buckets value", *argv);
+                       addattr16(n, maxlen, NHA_RES_GROUP_BUCKETS, buckets);
+               } else if (strcmp(*argv, "idle_timer") == 0) {
+                       __u32 idle_timer;
+                       NEXT_ARG();
+                       if (get_unsigned(&idle_timer, *argv, 0) ||
+                           idle_timer >= ~0UL / 100)
+                               invarg("invalid idle timer value", *argv);
+                       addattr32(n, maxlen, NHA_RES_GROUP_IDLE_TIMER,
+                                 idle_timer * 100);
+               } else if (strcmp(*argv, "unbalanced_timer") == 0) {
+                       __u32 unbalanced_timer;
+                       NEXT_ARG();
+                       if (get_unsigned(&unbalanced_timer, *argv, 0) ||
+                           unbalanced_timer >= ~0UL / 100)
+                               invarg("invalid unbalanced timer value", *argv);
+                       addattr32(n, maxlen, NHA_RES_GROUP_UNBALANCED_TIMER,
+                                 unbalanced_timer * 100);
+               } else {
+                       break;
+               }
+               argc--; argv++;
+       }
+       /* argv is currently the first unparsed argument, but ipnh_modify()
+        * will move to the next, so step back.
+        */
+       *argcp = argc + 1;
+       *argvp = argv - 1;
+       addattr_nest_end(n, nest);
+ }
+ static void parse_nh_group_type(struct nlmsghdr *n, int maxlen, int *argcp,
+                               char ***argvp)
+ {
+       char **argv = *argvp;
+       int argc = *argcp;
+       __u16 type;
+       NEXT_ARG();
+       type = read_nh_group_type(*argv);
+       if (type > NEXTHOP_GRP_TYPE_MAX)
+               invarg("\"type\" value is invalid\n", *argv);
+       switch (type) {
+       case NEXTHOP_GRP_TYPE_MPATH:
+               /* No additional arguments */
+               break;
+       case NEXTHOP_GRP_TYPE_RES:
+               parse_nh_group_type_res(n, maxlen, &argc, &argv);
+               break;
+       }
+       *argcp = argc;
+       *argvp = argv;
+       addattr16(n, maxlen, NHA_GROUP_TYPE, type);
+ }
+ static int ipnh_parse_id(const char *argv)
+ {
+       __u32 id;
+       if (get_unsigned(&id, argv, 0))
+               invarg("invalid id value", argv);
+       return id;
+ }
  static int ipnh_modify(int cmd, unsigned int flags, int argc, char **argv)
  {
        struct {