From cf2b40626bb6db3e22d6c990b79bf9c001eaee5d Mon Sep 17 00:00:00 2001 From: Garrett Kajmowicz Date: Tue, 27 Nov 2018 21:47:07 +0000 Subject: [PATCH] Merge pull request #36 in WARHOL/netmap from feature/NC-36419-upstream-vale-port-type-extraction to master * commit '0611cef314f524741c9ea3ad80bf3cd85634cc1a': Change constant names to reflect upstream standards. Add port type information to vale-ctl output. Add additional checks to identify a vale Physical port Add a port type return value for NETMAP_BDG_LIST command --- apps/vale-ctl/vale-ctl.c | 34 ++++++++++++++++++++++---- sys/dev/netmap/netmap_legacy.c | 1 + sys/dev/netmap/netmap_vale.c | 44 ++++++++++++++++++++++++++++++++++ sys/net/netmap.h | 13 ++++++++++ 4 files changed, 88 insertions(+), 4 deletions(-) diff --git a/apps/vale-ctl/vale-ctl.c b/apps/vale-ctl/vale-ctl.c index fc909144a..6dfb7ed8f 100644 --- a/apps/vale-ctl/vale-ctl.c +++ b/apps/vale-ctl/vale-ctl.c @@ -42,6 +42,32 @@ #include /* basename */ #include /* atoi, free */ +/* Text/UI versions of VALE port types to display. Type NaN is if + * we get a response type from the kernel outside the range we know + * how to interpret. + */ + +static const char TXT_VALE_PORT_T_ERROR[] = "ERR"; +static const char TXT_VALE_PORT_T_PHYS[] = "PHYS"; +static const char TXT_VALE_PORT_T_STACK[] = "STACK"; +static const char TXT_VALE_PORT_T_VIRT[] = "VIRT"; +static const char TXT_VALE_PORT_T_NAN[] = "NaN"; + +static const char* vale_port_type_to_text(uint port_type) { + switch (port_type) { + case VALE_PORT_T_ERROR: + return TXT_VALE_PORT_T_ERROR; + case VALE_PORT_T_PHYS: + return TXT_VALE_PORT_T_PHYS; + case VALE_PORT_T_STACK: + return TXT_VALE_PORT_T_STACK; + case VALE_PORT_T_VIRT: + return TXT_VALE_PORT_T_VIRT; + default: + return TXT_VALE_PORT_T_NAN; + } +} + /* XXX cut and paste from pkt-gen.c because I'm not sure whether this * program may include nm_util.h */ @@ -137,16 +163,16 @@ bdg_ctl(const char *name, int nr_cmd, int nr_arg, char *nmr_config, int nr_arg2) ND("Unable to obtain info for %s", name); perror(name); } else - D("%s at bridge:%d port:%d", name, nmr.nr_arg1, - nmr.nr_arg2); + D("%s at bridge:%d port:%d type:%s", name, nmr.nr_arg1, + nmr.nr_arg2, vale_port_type_to_text(nmr.nr_arg3)); break; } /* scan all the bridges and ports */ nmr.nr_arg1 = nmr.nr_arg2 = 0; for (; !ioctl(fd, NIOCGINFO, &nmr); nmr.nr_arg2++) { - D("bridge:%d port:%d %s", nmr.nr_arg1, nmr.nr_arg2, - nmr.nr_name); + D("bridge:%d port:%d type:%s %s", nmr.nr_arg1, nmr.nr_arg2, + vale_port_type_to_text(nmr.nr_arg3), nmr.nr_name); nmr.nr_name[0] = '\0'; } diff --git a/sys/dev/netmap/netmap_legacy.c b/sys/dev/netmap/netmap_legacy.c index 9159c1bce..c01c89060 100644 --- a/sys/dev/netmap/netmap_legacy.c +++ b/sys/dev/netmap/netmap_legacy.c @@ -324,6 +324,7 @@ nmreq_to_legacy(struct nmreq_header *hdr, struct nmreq *nmr) strlcpy(nmr->nr_name, hdr->nr_name, sizeof(nmr->nr_name)); nmr->nr_arg1 = req->nr_bridge_idx; nmr->nr_arg2 = req->nr_port_idx; + nmr->nr_arg3 = req->nr_port_type; break; } case NETMAP_REQ_PORT_HDR_SET: diff --git a/sys/dev/netmap/netmap_vale.c b/sys/dev/netmap/netmap_vale.c index e4cb8ea01..9aef13139 100644 --- a/sys/dev/netmap/netmap_vale.c +++ b/sys/dev/netmap/netmap_vale.c @@ -348,6 +348,28 @@ netmap_vale_list(struct nmreq_header *hdr) */ if (!strcmp(vpna->up.name, hdr->nr_name)) { req->nr_port_idx = i; /* port index */ + /* VALE port type logic */ + if (vpna->up.pdev && + vpna->up.na_hostvp && + vpna->up.na_vp) { + req->nr_port_type = VALE_PORT_T_PHYS; + } else if (!vpna->up.pdev && + vpna->up.na_hostvp && + vpna->up.na_vp) { + if (vpna->up.na_flags & NAF_HOST_RINGS) + req->nr_port_type = VALE_PORT_T_PHYS; + else + req->nr_port_type = VALE_PORT_T_STACK; + } else if (!vpna->up.pdev && + !vpna->up.na_hostvp && + vpna->up.na_vp) { + req->nr_port_type = VALE_PORT_T_VIRT; + } else { + D("Unknown VALE port %s with pdev: %p, hvp: %p, na_vp: %p", + vpna->up.name, vpna->up.pdev, vpna->up.na_hostvp, + vpna->up.na_vp); + req->nr_port_type = VALE_PORT_T_ERROR; + } break; } } @@ -373,6 +395,28 @@ netmap_vale_list(struct nmreq_header *hdr) /* write back the VALE switch name */ strlcpy(hdr->nr_name, vpna->up.name, sizeof(hdr->nr_name)); + /* VALE port type logic */ + if (vpna->up.pdev && + vpna->up.na_hostvp && + vpna->up.na_vp) { + req->nr_port_type = VALE_PORT_T_PHYS; + } else if (!vpna->up.pdev && + vpna->up.na_hostvp && + vpna->up.na_vp) { + if (vpna->up.na_flags & NAF_HOST_RINGS) + req->nr_port_type = VALE_PORT_T_PHYS; + else + req->nr_port_type = VALE_PORT_T_STACK; + } else if (!vpna->up.pdev && + !vpna->up.na_hostvp && + vpna->up.na_vp) { + req->nr_port_type = VALE_PORT_T_VIRT; + } else { + D("Unknown VALE port %s with pdev: %p, hvp: %p, na_vp: %p", + vpna->up.name, vpna->up.pdev, vpna->up.na_hostvp, + vpna->up.na_vp); + req->nr_port_type = VALE_PORT_T_ERROR; + } error = 0; goto out; } diff --git a/sys/net/netmap.h b/sys/net/netmap.h index 3376509ad..3d3e39103 100644 --- a/sys/net/netmap.h +++ b/sys/net/netmap.h @@ -662,11 +662,24 @@ struct nmreq_vale_detach { * nr_reqtype: NETMAP_REQ_VALE_LIST * List the ports of a VALE switch. */ + +/* Use the following port type values to indicate the type of port attached to + * the vale bridge + */ +enum { + VALE_PORT_T_ERROR = 0, + VALE_PORT_T_PHYS = 1, + VALE_PORT_T_STACK = 2, + VALE_PORT_T_VIRT = 3, +}; + struct nmreq_vale_list { /* Name of the VALE port (valeXXX:YYY) or empty. */ uint16_t nr_bridge_idx; uint16_t pad1; uint32_t nr_port_idx; + /* Type of the VALE port */ + uint8_t nr_port_type; }; /*