]> git.proxmox.com Git - mirror_iproute2.git/blobdiff - tc/f_flower.c
f_flower: fix build with musl libc
[mirror_iproute2.git] / tc / f_flower.c
index 9bddf7be3f88dc69d52e3ac5942030f3c3ea1daf..9659e894dd1f93b4f773525f38270ecadf174b67 100644 (file)
@@ -14,6 +14,7 @@
 #include <unistd.h>
 #include <string.h>
 #include <net/if.h>
+#include <linux/limits.h>
 #include <linux/if_arp.h>
 #include <linux/if_ether.h>
 #include <linux/ip.h>
@@ -473,27 +474,6 @@ static int flower_port_attr_type(__u8 ip_proto, enum flower_endpoint endpoint)
                return -1;
 }
 
-static int flower_parse_port(char *str, __u8 ip_proto,
-                            enum flower_endpoint endpoint,
-                            struct nlmsghdr *n)
-{
-       int ret;
-       int type;
-       __be16 port;
-
-       type = flower_port_attr_type(ip_proto, endpoint);
-       if (type < 0)
-               return -1;
-
-       ret = get_be16(&port, str, 10);
-       if (ret)
-               return -1;
-
-       addattr16(n, MAX_MSG, type, port);
-
-       return 0;
-}
-
 static int flower_port_range_attr_type(__u8 ip_proto, enum flower_endpoint type,
                                       __be16 *min_port_type,
                                       __be16 *max_port_type)
@@ -510,47 +490,39 @@ static int flower_port_range_attr_type(__u8 ip_proto, enum flower_endpoint type,
        } else {
                return -1;
        }
-
        return 0;
 }
 
-static int flower_parse_port_range(__be16 *min, __be16 *max, __u8 ip_proto,
-                                  enum flower_endpoint endpoint,
-                                  struct nlmsghdr *n)
+static int flower_parse_port(char *str, __u8 ip_proto,
+                            enum flower_endpoint endpoint,
+                            struct nlmsghdr *n)
 {
-       __be16 min_port_type, max_port_type;
-
-       if (flower_port_range_attr_type(ip_proto, endpoint, &min_port_type,
-                                       &max_port_type))
-               return -1;
-
-       addattr16(n, MAX_MSG, min_port_type, *min);
-       addattr16(n, MAX_MSG, max_port_type, *max);
+       __u16 min, max;
+       int ret;
 
-       return 0;
-}
+       ret = sscanf(str, "%hu-%hu", &min, &max);
 
-static int get_range(__be16 *min, __be16 *max, char *argv)
-{
-       char *r;
+       if (ret == 1) {
+               int type;
 
-       r = strchr(argv, '-');
-       if (r) {
-               *r = '\0';
-               if (get_be16(min, argv, 10)) {
-                       fprintf(stderr, "invalid min range\n");
-                       return -1;
-               }
-               if (get_be16(max, r + 1, 10)) {
-                       fprintf(stderr, "invalid max range\n");
+               type = flower_port_attr_type(ip_proto, endpoint);
+               if (type < 0)
                        return -1;
-               }
-               if (htons(*max) <= htons(*min)) {
+               addattr16(n, MAX_MSG, type, htons(min));
+       } else if (ret == 2) {
+               __be16 min_port_type, max_port_type;
+
+               if (max <= min) {
                        fprintf(stderr, "max value should be greater than min value\n");
                        return -1;
                }
+               if (flower_port_range_attr_type(ip_proto, endpoint,
+                                               &min_port_type, &max_port_type))
+                       return -1;
+
+               addattr16(n, MAX_MSG, min_port_type, htons(min));
+               addattr16(n, MAX_MSG, max_port_type, htons(max));
        } else {
-               fprintf(stderr, "Illegal range format\n");
                return -1;
        }
        return 0;
@@ -1123,54 +1095,20 @@ static int flower_parse_opt(struct filter_util *qu, char *handle,
                                return -1;
                        }
                } else if (matches(*argv, "dst_port") == 0) {
-                       __be16 min, max;
-
                        NEXT_ARG();
-                       if (matches(*argv, "range") == 0) {
-                               NEXT_ARG();
-                               ret = get_range(&min, &max, *argv);
-                               if (ret < 0)
-                                       return -1;
-                               ret = flower_parse_port_range(&min, &max,
-                                                             ip_proto,
-                                                             FLOWER_ENDPOINT_DST,
-                                                             n);
-                               if (ret < 0) {
-                                       fprintf(stderr, "Illegal \"dst_port range\"\n");
-                                       return -1;
-                               }
-                       } else {
-                               ret = flower_parse_port(*argv, ip_proto,
-                                                       FLOWER_ENDPOINT_DST, n);
-                               if (ret < 0) {
-                                       fprintf(stderr, "Illegal \"dst_port\"\n");
-                                       return -1;
-                               }
+                       ret = flower_parse_port(*argv, ip_proto,
+                                               FLOWER_ENDPOINT_DST, n);
+                       if (ret < 0) {
+                               fprintf(stderr, "Illegal \"dst_port\"\n");
+                               return -1;
                        }
                } else if (matches(*argv, "src_port") == 0) {
-                       __be16 min, max;
-
                        NEXT_ARG();
-                       if (matches(*argv, "range") == 0) {
-                               NEXT_ARG();
-                               ret = get_range(&min, &max, *argv);
-                               if (ret < 0)
-                                       return -1;
-                               ret = flower_parse_port_range(&min, &max,
-                                                             ip_proto,
-                                                             FLOWER_ENDPOINT_SRC,
-                                                             n);
-                               if (ret < 0) {
-                                       fprintf(stderr, "Illegal \"src_port range\"\n");
-                                       return -1;
-                               }
-                       } else {
-                               ret = flower_parse_port(*argv, ip_proto,
-                                                       FLOWER_ENDPOINT_SRC, n);
-                               if (ret < 0) {
-                                       fprintf(stderr, "Illegal \"src_port\"\n");
-                                       return -1;
-                               }
+                       ret = flower_parse_port(*argv, ip_proto,
+                                               FLOWER_ENDPOINT_SRC, n);
+                       if (ret < 0) {
+                               fprintf(stderr, "Illegal \"src_port\"\n");
+                               return -1;
                        }
                } else if (matches(*argv, "tcp_flags") == 0) {
                        NEXT_ARG();
@@ -1589,17 +1527,24 @@ static void flower_print_port(char *name, struct rtattr *attr)
 static void flower_print_port_range(char *name, struct rtattr *min_attr,
                                    struct rtattr *max_attr)
 {
-       SPRINT_BUF(namefrm);
-       SPRINT_BUF(out);
-       size_t done;
-
        if (!min_attr || !max_attr)
                return;
 
-       done = sprintf(out, "%u", rta_getattr_be16(min_attr));
-       sprintf(out + done, "-%u", rta_getattr_be16(max_attr));
-       sprintf(namefrm, "\n  %s %%s", name);
-       print_string(PRINT_ANY, name, namefrm, out);
+       if (is_json_context()) {
+               open_json_object(name);
+               print_hu(PRINT_JSON, "start", NULL, rta_getattr_be16(min_attr));
+               print_hu(PRINT_JSON, "end", NULL, rta_getattr_be16(max_attr));
+               close_json_object();
+       } else {
+               SPRINT_BUF(namefrm);
+               SPRINT_BUF(out);
+               size_t done;
+
+               done = sprintf(out, "%u", rta_getattr_be16(min_attr));
+               sprintf(out + done, "-%u", rta_getattr_be16(max_attr));
+               sprintf(namefrm, "\n  %s %%s", name);
+               print_string(PRINT_ANY, name, namefrm, out);
+       }
 }
 
 static void flower_print_tcp_flags(const char *name, struct rtattr *flags_attr,
@@ -1911,12 +1856,12 @@ static int flower_print_opt(struct filter_util *qu, FILE *f,
 
        if (!flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_DST,
                                         &min_port_type, &max_port_type))
-               flower_print_port_range("dst_port range",
+               flower_print_port_range("dst_port",
                                        tb[min_port_type], tb[max_port_type]);
 
        if (!flower_port_range_attr_type(ip_proto, FLOWER_ENDPOINT_SRC,
                                         &min_port_type, &max_port_type))
-               flower_print_port_range("src_port range",
+               flower_print_port_range("src_port",
                                        tb[min_port_type], tb[max_port_type]);
 
        flower_print_tcp_flags("tcp_flags", tb[TCA_FLOWER_KEY_TCP_FLAGS],