main entry point for dummynet list functions. co.do_pipe indicates * which function we want to support. * av may contain filtering arguments, either individual entries * or ranges, or lists (space or commas are valid separators). * Format for a range can be n1-n2 or n3 n4 n5 ... * In a range n1 must be <= n2, otherwise the range is ignored. * A number 'n4' is translate in a range 'n4-n4' *
| 1912 | * All number must be > 0 and < DN_MAX_ID-1 |
| 1913 | */ |
| 1914 | void |
| 1915 | dummynet_list(int ac, char *av[], int show_counters) |
| 1916 | { |
| 1917 | struct dn_id *oid, *x = NULL; |
| 1918 | int ret, i; |
| 1919 | int n; /* # of ranges */ |
| 1920 | u_int buflen, l; |
| 1921 | u_int max_size; /* largest obj passed up */ |
| 1922 | |
| 1923 | (void)show_counters; // XXX unused, but we should use it. |
| 1924 | ac--; |
| 1925 | av++; /* skip 'list' | 'show' word */ |
| 1926 | |
| 1927 | n = parse_range(ac, av, NULL, 0); /* Count # of ranges. */ |
| 1928 | |
| 1929 | /* Allocate space to store ranges */ |
| 1930 | l = sizeof(*oid) + sizeof(uint32_t) * n * 2; |
| 1931 | oid = safe_calloc(1, l); |
| 1932 | oid_fill(oid, l, DN_CMD_GET, DN_API_VERSION); |
| 1933 | |
| 1934 | if (n > 0) /* store ranges in idx */ |
| 1935 | parse_range(ac, av, (uint32_t *)(oid + 1), n*2); |
| 1936 | /* |
| 1937 | * Compute the size of the largest object returned. If the |
| 1938 | * response leaves at least this much spare space in the |
| 1939 | * buffer, then surely the response is complete; otherwise |
| 1940 | * there might be a risk of truncation and we will need to |
| 1941 | * retry with a larger buffer. |
| 1942 | * XXX don't bother with smaller structs. |
| 1943 | */ |
| 1944 | max_size = sizeof(struct dn_fs); |
| 1945 | if (max_size < sizeof(struct dn_sch)) |
| 1946 | max_size = sizeof(struct dn_sch); |
| 1947 | if (max_size < sizeof(struct dn_flow)) |
| 1948 | max_size = sizeof(struct dn_flow); |
| 1949 | |
| 1950 | switch (g_co.do_pipe) { |
| 1951 | case 1: |
| 1952 | oid->subtype = DN_LINK; /* list pipe */ |
| 1953 | break; |
| 1954 | case 2: |
| 1955 | oid->subtype = DN_FS; /* list queue */ |
| 1956 | break; |
| 1957 | case 3: |
| 1958 | oid->subtype = DN_SCH; /* list sched */ |
| 1959 | break; |
| 1960 | } |
| 1961 | |
| 1962 | /* |
| 1963 | * Ask the kernel an estimate of the required space (result |
| 1964 | * in oid.id), unless we are requesting a subset of objects, |
| 1965 | * in which case the kernel does not give an exact answer. |
| 1966 | * In any case, space might grow in the meantime due to the |
| 1967 | * creation of new queues, so we must be prepared to retry. |
| 1968 | */ |
| 1969 | if (n > 0) { |
| 1970 | buflen = 4*1024; |
| 1971 | } else { |
no test coverage detected