diff options
Diffstat (limited to 'usr/src/cmd')
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile | 2 | ||||
| -rw-r--r-- | usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c | 77 | ||||
| -rw-r--r-- | usr/src/cmd/dladm/dladm.c | 130 | ||||
| -rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/Makefile.files | 1 | ||||
| -rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/genunix.c | 7 | ||||
| -rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/qqcache.c | 117 | ||||
| -rw-r--r-- | usr/src/cmd/mdb/common/modules/genunix/qqcache.h | 40 |
7 files changed, 354 insertions, 20 deletions
diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile index 4e3dd8259a..9b11174c49 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/Makefile @@ -22,7 +22,7 @@ # # Copyright 2009 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. -# Copyright (c) 2018, Joyent, Inc. +# Copyright 2018 Joyent, Inc. # PROG= snoop diff --git a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c index a0768c2234..3da8c57f44 100644 --- a/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c +++ b/usr/src/cmd/cmd-inet/usr.sbin/snoop/snoop_svp.c @@ -322,6 +322,11 @@ do_svp_log_ack(void *data, int len) case SVP_LOG_VL3: rlen = sizeof (svp_log_vl3_t); break; +#if 0 /* XXX KEBE SAYS ROUTE */ + case SVP_LOG_ROUTE: + rlen = sizeof (svp_log_route_t); + break; +#endif default: /* * If we don't know the type of log record we have, @@ -362,6 +367,33 @@ do_svp_log_ack(void *data, int len) ntohl(u.vl3->svl3_vnetid)); u.vl3++; break; +#if 0 /* XXX KEBE SAYS ROUTE */ + case SVP_LOG_ROUTE: + show_printf("%8s Source Vnet = %u", "", + ntohl(u.vr->svlr_src_vnetid)); + show_printf("%8s Source VLAN = %hu", "", + ntohs(u.vr->svlr_src_vlan)); + + prefixlen = u.vr->svlr_src_prefixlen; + is_host = prefixlen == 128 ? B_TRUE : B_FALSE; + show_printf("%8s Source %s = %s", "", + is_host ? "address" : "subnet", + svp_addr_str(u.vr->svlr_srcip, &prefixlen)); + show_printf("%8s Destination DC id = %u", "", + ntohl(u.vr->svlr_dcid)); + show_printf("%8s Destination Vnet = %u", "", + ntohl(u.vr->svlr_dst_vnetid)); + show_printf("%8s Destination VLAN = %hu", "", + ntohs(u.vr->svlr_dst_vlan)); + + prefixlen = u.vr->svlr_dst_prefixlen; + is_host = prefixlen == 128 ? B_TRUE : B_FALSE; + show_printf("%8s Destination %s = %s", "", + is_host ? "address" : "subnet", + svp_addr_str(u.vr->svlr_dstip, &prefixlen)); + u.vr++; + break; +#endif } len -= rlen; @@ -423,6 +455,39 @@ do_svp_shootdown(void *data, int len) ether_ntoa((struct ether_addr *)sd->svsd_mac)); } +#if 0 /* XXX KEBE SAYS ROUTE */ +static void +do_svp_route_req(void *data, int len) +{ + svp_route_req_t *req = data; + + show_printf("Vnet = %u", ntohl(req->srr_vnetid)); + show_printf("VLAN = %hu", ntohs(req->srr_vlan)); + show_printf("Source Address = %s", svp_addr_str(req->srr_srcip, NULL)); + show_printf("Destination Address = %s", svp_addr_str(req->srr_dstip, + NULL)); +} + +static void +do_svp_route_ack(void *data, int len) +{ + svp_route_ack_t *ack = data; + + show_printf("Status = %s", svp_status_str(ntohl(ack->sra_status))); + show_printf("Remote DC Id = %u", ntohl(ack->sra_dcid)); + show_printf("Remote Vnet = %u", ntohl(ack->sra_vnetid)); + show_printf("Remote VLAN = %hu", ntohs(ack->sra_vlan)); + show_printf("Remote UL3 Address = %s", svp_addr_str(ack->sra_ip, NULL)); + show_printf("Remote UL3 Port = %hu", ntohs(ack->sra_port)); + show_printf("Source MAC Address = %s", + ether_ntoa((struct ether_addr *)ack->sra_srcmac)); + show_printf("Destination MAC Address = %s", + ether_ntoa((struct ether_addr *)ack->sra_dstmac)); + show_printf("Source IP Prefix = %hhu", ack->sra_src_pfx); + show_printf("Destination IP Prefix = %hhu", ack->sra_dst_pfx); +} +#endif + static struct svp_len_tbl { uint16_t slt_op; size_t slt_len; @@ -441,6 +506,10 @@ static struct svp_len_tbl { { SVP_R_LOG_RM, sizeof (svp_lrm_req_t) }, { SVP_R_LOG_RM_ACK, sizeof (svp_lrm_ack_t) }, { SVP_R_SHOOTDOWN, sizeof (svp_shootdown_t) }, +#if 0 /* XXX KEBE SAYS ROUTE */ + { SVP_R_ROUTE_REQ, sizeof (svp_route_req_t) }, + { SVP_R_ROUTE_ACK, sizeof (svp_route_ack_t) } +#endif }; static boolean_t @@ -548,6 +617,14 @@ interpret_svp(int flags, char *data, int fraglen) case SVP_R_SHOOTDOWN: do_svp_shootdown(req, fraglen); break; +#if 0 /* XXX KEBE SAYS ROUTE */ + case SVP_R_ROUTE_REQ: + do_svp_route_req(req, fraglen); + break; + case SVP_R_ROUTE_ACK: + do_svp_route_ack(req, fraglen); + break; +#endif } show_space(); diff --git a/usr/src/cmd/dladm/dladm.c b/usr/src/cmd/dladm/dladm.c index c59926be94..590f693a66 100644 --- a/usr/src/cmd/dladm/dladm.c +++ b/usr/src/cmd/dladm/dladm.c @@ -21,7 +21,7 @@ /* * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2017 Joyent, Inc. + * Copyright 2018 Joyent, Inc. * Copyright 2016 Nexenta Systems, Inc. * Copyright 2020 Peter Tribble. */ @@ -420,13 +420,14 @@ static cmd_t cmds[] = { " show-bridge -t [-p] [-o <field>,...] [-s [-i <interval>]]" " <bridge>\n" }, { "create-overlay", do_create_overlay, - " create-overlay [-t] -e <encap> -s <search> -v <vnetid>\n" + " create-overlay [-t] [-d <dcid>] -e <encap> -s <search> " + "-v <vnetid>\n" "\t\t [ -p <prop>=<value>[,...]] <overlay>" }, { "delete-overlay", do_delete_overlay, " delete-overlay <overlay>" }, { "modify-overlay", do_modify_overlay, - " modify-overlay -d mac | -f | -s mac=ip:port " - "<overlay>" }, + " modify-overlay -d [dcid/]mac | -f | -s [dcid/]mac=ip:port " + " | -p prop=value[,...] <overlay>" }, { "show-overlay", do_show_overlay, " show-overlay [-f | -t] [[-p] -o <field>,...] " "[<overlay>]\n" }, @@ -1464,12 +1465,14 @@ static const struct option overlay_create_lopts[] = { { "search", required_argument, NULL, 's' }, { "temporary", no_argument, NULL, 't' }, { "vnetid", required_argument, NULL, 'v' }, + { "dcid", optional_argument, NULL, 'd' }, { NULL, 0, NULL, 0 } }; static const struct option overlay_modify_lopts[] = { { "delete-entry", required_argument, NULL, 'd' }, { "flush-table", no_argument, NULL, 'f' }, + { "prop", required_argument, NULL, 'p' }, { "set-entry", required_argument, NULL, 's' }, { NULL, 0, NULL, 0 } }; @@ -9892,15 +9895,26 @@ do_create_overlay(int argc, char *argv[], const char *use) char name[MAXLINKNAMELEN]; dladm_status_t status; uint32_t flags = DLADM_OPT_ACTIVE | DLADM_OPT_PERSIST; + uint32_t dcid = 0; uint64_t vid; boolean_t havevid = B_FALSE; char propstr[DLADM_STRSIZE]; dladm_arg_list_t *proplist = NULL; bzero(propstr, sizeof (propstr)); - while ((opt = getopt_long(argc, argv, ":te:v:p:s:", + while ((opt = getopt_long(argc, argv, ":td:e:v:p:s:", overlay_create_lopts, NULL)) != -1) { switch (opt) { + case 'd': + errno = 0; + dcid = strtoul(optarg, &endp, 10); + if (*endp != '\0' || (dcid == 0 && errno == EINVAL)) + die("couldn't parse datacenter id: %s", + optarg); + /* XXX If we go 64-bit, add check for > UINT32_MAX. */ + if (dcid == ULONG_MAX && errno == ERANGE) + die("datacenter id too large: %s", optarg); + break; case 'e': encap = optarg; break; @@ -9917,6 +9931,7 @@ do_create_overlay(int argc, char *argv[], const char *use) die("property list too long '%s'", propstr); break; case 'v': + errno = 0; vid = strtoul(optarg, &endp, 10); if (*endp != '\0' || (vid == 0 && errno == EINVAL)) die("couldn't parse virtual networkd id: %s", @@ -9959,7 +9974,7 @@ do_create_overlay(int argc, char *argv[], const char *use) != DLADM_STATUS_OK) die("invalid overlay property"); - status = dladm_overlay_create(handle, name, encap, search, vid, + status = dladm_overlay_create(handle, name, encap, search, vid, dcid, proplist, &errlist, flags); dladm_free_props(proplist); if (status != DLADM_STATUS_OK) { @@ -9989,7 +10004,7 @@ do_delete_overlay(int argc, char *argv[], const char *use) typedef struct showoverlay_state { ofmt_handle_t sho_ofmt; - const char *sho_linkname; + const char *sho_linkname; dladm_overlay_propinfo_handle_t sho_info; uint8_t sho_value[DLADM_OVERLAY_PROP_SIZEMAX]; uint32_t sho_size; @@ -10080,6 +10095,12 @@ print_overlay_value(char *outbuf, uint_t bufsize, uint_t type, const void *pbuf, case OVERLAY_PROP_T_STRING: (void) snprintf(outbuf, bufsize, "%s", pbuf); break; + case OVERLAY_PROP_T_ETHER: + if (ether_ntoa_r((struct ether_addr *)pbuf, outbuf) == NULL) { + warn("malformed overlay ethernet property\n"); + (void) snprintf(outbuf, bufsize, "--"); + } + break; default: abort(); } @@ -10428,7 +10449,7 @@ do_show_overlay(int argc, char *argv[], const char *use) int i, opt; datalink_id_t linkid = DATALINK_ALL_LINKID; dladm_status_t status; - int (*funcp)(dladm_handle_t, datalink_id_t, void *); + int (*funcp)(dladm_handle_t, datalink_id_t, void *); char *fields_str = NULL; const ofmt_field_t *fieldsp; ofmt_status_t oferr; @@ -10498,17 +10519,54 @@ do_show_overlay(int argc, char *argv[], const char *use) } static void +parse_overlay_mac(const char *s, uint32_t *dcidp, struct ether_addr *ep) +{ + const char *slash; + + *dcidp = 0; + + if ((slash = strchr(s, '/')) != NULL) { + ulong_t dcval = 0; + size_t slen = (size_t)(slash - s) + 1; + + /* + * If present the dcid must be at least 1 digit, and <= + * UINT32_MAX (10 digits + 1 for NUL). + */ + if (slen < 2 || slen > 11) + die("invalid mac specification: %s\n", s); + + char dcstr[slen]; + + (void) strlcpy(dcstr, s, slen); + errno = 0; + if ((dcval = strtoul(dcstr, NULL, 10)) == 0 && errno != 0) + die("invalid data center id: %s\n", dcstr); + /* XXX if we become 64-bit, check for results > UINT32_MAX */ + + *dcidp = (uint32_t)dcval; + /* Move s past '/' */ + s = slash + 1; + } + + if (ether_aton_r(s, ep) == NULL) + die("invalid mac specification: %s\n", s); +} + +static void do_modify_overlay(int argc, char *argv[], const char *use) { int opt, ocnt = 0; - boolean_t flush, set, delete; + boolean_t flush, set, delete, setprop; + uint32_t dcid = 0; struct ether_addr e; char *dest; datalink_id_t linkid = DATALINK_ALL_LINKID; dladm_status_t status; + char propstr[DLADM_STRSIZE] = { 0 }; - flush = set = delete = B_FALSE; - while ((opt = getopt_long(argc, argv, ":fd:s:", overlay_modify_lopts, + flush = set = delete = setprop = B_FALSE; + while ((opt = getopt_long(argc, argv, ":fd:p:s:", overlay_modify_lopts, NULL)) != -1) { switch (opt) { case 'd': @@ -10516,8 +10574,7 @@ do_modify_overlay(int argc, char *argv[], const char *use) die_optdup('d'); delete = B_TRUE; ocnt++; - if (ether_aton_r(optarg, &e) == NULL) - die("invalid mac address: %s\n", optarg); + parse_overlay_mac(optarg, &dcid, &e); break; case 'f': if (flush == B_TRUE) @@ -10525,6 +10582,16 @@ do_modify_overlay(int argc, char *argv[], const char *use) flush = B_TRUE; ocnt++; break; + case 'p': + if (setprop == B_TRUE) + die_optdup('p'); + setprop = B_TRUE; + (void) strlcat(propstr, optarg, DLADM_STRSIZE); + if (strlcat(propstr, ",", DLADM_STRSIZE) >= + DLADM_STRSIZE) + die("property list too long '%s'", propstr); + ocnt++; + break; case 's': if (set == B_TRUE) die_optdup('s'); @@ -10536,8 +10603,7 @@ do_modify_overlay(int argc, char *argv[], const char *use) if (dest == NULL) die("malformed value, expected mac=dest, " "got: %s\n", optarg); - if (ether_aton_r(optarg, &e) == NULL) - die("invalid mac address: %s\n", optarg); + parse_overlay_mac(optarg, &dcid, &e); break; default: die_opterr(optopt, opt, use); @@ -10545,9 +10611,9 @@ do_modify_overlay(int argc, char *argv[], const char *use) } if (ocnt == 0) - die("need to specify one of -d, -f, or -s"); + die("need to specify one of -d, -f, -p, or -s"); if (ocnt > 1) - die("only one of -d, -f, or -s may be used"); + die("only one of -d, -f, -p, or -s may be used"); if (argv[optind] == NULL) die("missing required overlay device\n"); @@ -10568,17 +10634,43 @@ do_modify_overlay(int argc, char *argv[], const char *use) } if (delete == B_TRUE) { - status = dladm_overlay_cache_delete(handle, linkid, &e); + status = dladm_overlay_cache_delete(handle, linkid, dcid, &e); if (status != DLADM_STATUS_OK) die_dlerr(status, "failed to flush target %s from " "overlay target cache %s", optarg, argv[optind]); } if (set == B_TRUE) { - status = dladm_overlay_cache_set(handle, linkid, &e, dest); + status = dladm_overlay_cache_set(handle, linkid, dcid, &e, + dest); if (status != DLADM_STATUS_OK) die_dlerr(status, "failed to set target %s for overlay " "target cache %s", optarg, argv[optind]); } + if (setprop == B_TRUE) { + dladm_arg_list_t *proplist = NULL; + uint_t i; + + if (dladm_parse_link_props(propstr, &proplist, B_FALSE) + != DLADM_STATUS_OK) + die("invalid overlay property"); + + for (i = 0; i < proplist->al_count; i++) { + dladm_status_t status; + + status = dladm_overlay_setprop(handle, linkid, + proplist->al_info[i].ai_name, + proplist->al_info[i].ai_val, + proplist->al_info[i].ai_count); + + if (status != DLADM_STATUS_OK) { + die_dlerr(status, "failed to set property %s " + "for overlay device %s", + proplist->al_info[i].ai_name, argv[optind]); + } + } + + dladm_free_props(proplist); + } } diff --git a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files index d371cf70fe..05ab8fe59c 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/Makefile.files +++ b/usr/src/cmd/mdb/common/modules/genunix/Makefile.files @@ -71,6 +71,7 @@ GENUNIX_SRCS = \ nvpair.c \ pci.c \ pg.c \ + qqcache.c \ rctl.c \ refhash.c \ refstr.c \ diff --git a/usr/src/cmd/mdb/common/modules/genunix/genunix.c b/usr/src/cmd/mdb/common/modules/genunix/genunix.c index 32370ba7e1..e0f21979e9 100644 --- a/usr/src/cmd/mdb/common/modules/genunix/genunix.c +++ b/usr/src/cmd/mdb/common/modules/genunix/genunix.c @@ -98,6 +98,7 @@ #include "nvpair.h" #include "pci.h" #include "pg.h" +#include "qqcache.h" #include "rctl.h" #include "refhash.h" #include "sobj.h" @@ -4788,6 +4789,12 @@ static const mdb_walker_t walkers[] = { { "pcie_bus", "walk all pcie_bus_t's", pcie_bus_walk_init, pcie_bus_walk_step, NULL }, + /* from qqcache.c */ + { QQCACHE_WALK_NAME, QQCACHE_WALK_DESC, + qqcache_walk_init_cache, qqcache_walk_step, qqcache_walk_fini }, + { QQCACHE_HASH_WALK_NAME, QQCACHE_HASH_WALK_DESC, + qqcache_walk_init_hash, qqcache_walk_step, qqcache_walk_fini }, + /* from rctl.c */ { "rctl_dict_list", "walk all rctl_dict_entry_t's from rctl_lists", rctl_dict_walk_init, rctl_dict_walk_step, NULL }, diff --git a/usr/src/cmd/mdb/common/modules/genunix/qqcache.c b/usr/src/cmd/mdb/common/modules/genunix/qqcache.c new file mode 100644 index 0000000000..a2ba1463b9 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/qqcache.c @@ -0,0 +1,117 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +#include <mdb/mdb_modapi.h> +#include <mdb/mdb_ctf.h> + +#include <sys/qqcache.h> +#include <sys/qqcache_impl.h> + +#include "qqcache.h" + +typedef struct qqcache_walk_data { + size_t qwd_link_off; +} qqcache_walk_data_t; + +typedef struct mdb_qqcache { + size_t qqc_link_off; + size_t qqc_nbuckets; +} mdb_qqcache_t; + +static int +qqcache_walk_init(mdb_walk_state_t *wsp, boolean_t use_hash) +{ + qqcache_walk_data_t *qwd; + uintptr_t base; + size_t i, n, qqc_list_sz; + int cache_off, bucket_off, list_off; + mdb_qqcache_t qc; + + /* mdb_ctf_offsetof_by_name will print any errors */ + cache_off = mdb_ctf_offsetof_by_name("qqcache_t", "qqc_lists"); + if (cache_off == -1) + return (WALK_ERR); + + bucket_off = mdb_ctf_offsetof_by_name("qqcache_t", "qqc_buckets"); + if (bucket_off == -1) + return (WALK_ERR); + + list_off = mdb_ctf_offsetof_by_name("qqcache_list_t", "qqcl_list"); + if (list_off == -1) + return (WALK_ERR); + + /* mdb_ctf_sizeof_by_name will print any errors */ + qqc_list_sz = mdb_ctf_sizeof_by_name("qqcache_list_t"); + if (qqc_list_sz == -1) + return (WALK_ERR); + + if (mdb_ctf_vread(&qc, "qqcache_t", "mdb_qqcache_t", wsp->walk_addr, + 0) == -1) { + mdb_warn("failed to read qqcache_t at %#lx", wsp->walk_addr); + return (WALK_ERR); + } + + qwd = wsp->walk_data = mdb_zalloc(sizeof (*qwd), UM_SLEEP); + qwd->qwd_link_off = qc.qqc_link_off; + + if (use_hash) { + base = wsp->walk_addr + bucket_off; + n = qc.qqc_nbuckets; + } else { + base = wsp->walk_addr + cache_off; + n = QQCACHE_NUM_LISTS; + } + + for (i = 0; i < n; i++) { + wsp->walk_addr = base + i * qqc_list_sz + list_off; + + if (mdb_layered_walk("list", wsp) == -1) { + mdb_warn("can't walk qqcache_t"); + mdb_free(qwd, sizeof (*qwd)); + return (WALK_ERR); + } + } + + return (WALK_NEXT); +} + +int +qqcache_walk_init_cache(mdb_walk_state_t *wsp) +{ + return (qqcache_walk_init(wsp, B_FALSE)); +} + +int +qqcache_walk_init_hash(mdb_walk_state_t *wsp) +{ + return (qqcache_walk_init(wsp, B_TRUE)); +} + +int +qqcache_walk_step(mdb_walk_state_t *wsp) +{ + qqcache_walk_data_t *qwd = wsp->walk_data; + uintptr_t addr = wsp->walk_addr - qwd->qwd_link_off; + + return (wsp->walk_callback(addr, wsp->walk_layer, wsp->walk_cbdata)); +} + +void +qqcache_walk_fini(mdb_walk_state_t *wsp) +{ + qqcache_walk_data_t *qwd = wsp->walk_data; + + mdb_free(qwd, sizeof (*qwd)); +} diff --git a/usr/src/cmd/mdb/common/modules/genunix/qqcache.h b/usr/src/cmd/mdb/common/modules/genunix/qqcache.h new file mode 100644 index 0000000000..c0d1d14fe6 --- /dev/null +++ b/usr/src/cmd/mdb/common/modules/genunix/qqcache.h @@ -0,0 +1,40 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent Inc. + */ + +#ifndef _MDB_QQCACHE_H +#define _MDB_QQCACHE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#define QQCACHE_WALK_NAME "qqcache" +#define QQCACHE_WALK_DESC "walk a qqcache (2Q cache)" + +#define QQCACHE_HASH_WALK_NAME "qqhash" +#define QQCACHE_HASH_WALK_DESC "walk a qqcache (2Q cache) via the hash buckets" + +struct mdb_walk_state; + +extern int qqcache_walk_init_cache(struct mdb_walk_state *); +extern int qqcache_walk_init_hash(struct mdb_walk_state *); +extern int qqcache_walk_step(struct mdb_walk_state *); +extern void qqcache_walk_fini(struct mdb_walk_state *); + +#ifdef __cplusplus +} +#endif + +#endif /* _MDB_QQCACHE_H */ |
