On Wed, May 03, 2017 at 12:06:01PM +0200, Reyk Floeter wrote: > Hi, > > the attached diff adds support for rdomains in vmd. > > In vm.conf, add an interface to a specified rdomain. local interfaces > work as expected, but the host-side routing and PF has to be done in > the non-default rdomain as well. > > vm "foo" { > local interface rdomain 1 > interface { > rdomain 2 > } > ... > } > > Or add all VM interfaces on a switch to a specified rdomain: > > switch "bar" { > rdomain 1 > ... > } > > OK? >
no objections, ok mlarkin if you didn't already get to this > Reyk > > Index: usr.sbin/vmd/config.c > =================================================================== > RCS file: /cvs/src/usr.sbin/vmd/config.c,v > retrieving revision 1.30 > diff -u -p -u -p -r1.30 config.c > --- usr.sbin/vmd/config.c 21 Apr 2017 07:03:26 -0000 1.30 > +++ usr.sbin/vmd/config.c 3 May 2017 10:02:58 -0000 > @@ -282,6 +282,9 @@ config_setvm(struct privsep *ps, struct > } > } > > + /* non-default rdomain (requires VMIFF_RDOMAIN below) */ > + vif->vif_rdomain = vmc->vmc_ifrdomain[i]; > + > /* Set the interface status */ > vif->vif_flags = > vmc->vmc_ifflags[i] & (VMIFF_UP|VMIFF_OPTMASK); > Index: usr.sbin/vmd/parse.y > =================================================================== > RCS file: /cvs/src/usr.sbin/vmd/parse.y,v > retrieving revision 1.28 > diff -u -p -u -p -r1.28 parse.y > --- usr.sbin/vmd/parse.y 3 May 2017 08:21:57 -0000 1.28 > +++ usr.sbin/vmd/parse.y 3 May 2017 10:02:59 -0000 > @@ -116,7 +116,7 @@ typedef struct { > > %token INCLUDE ERROR > %token ADD BOOT DISABLE DISK DOWN ENABLE GROUP INTERFACE LLADDR LOCAL > LOCKED > -%token MEMORY NIFS OWNER PATH PREFIX SIZE SWITCH UP VM VMID > +%token MEMORY NIFS OWNER PATH PREFIX RDOMAIN SIZE SWITCH UP VM VMID > %token <v.number> NUMBER > %token <v.string> STRING > %type <v.lladdr> lladdr > @@ -263,6 +263,14 @@ switch_opts : disable { > | LOCKED LLADDR { > vsw->sw_flags |= VMIFF_LOCKED; > } > + | RDOMAIN NUMBER { > + if ($2 < 0 || $2 > RT_TABLEID_MAX) { > + yyerror("invalid rdomain: %lld", $2); > + YYERROR; > + } > + vsw->sw_flags |= VMIFF_RDOMAIN; > + vsw->sw_rdomain = $2; > + } > | updown { > if ($1) > vsw->sw_flags |= VMIFF_UP; > @@ -532,6 +540,14 @@ iface_opts : SWITCH string { > vmc.vmc_ifflags[vcp_nnics] |= VMIFF_LOCKED; > memcpy(vcp->vcp_macs[vcp_nnics], $3, ETHER_ADDR_LEN); > } > + | RDOMAIN NUMBER { > + if ($2 < 0 || $2 > RT_TABLEID_MAX) { > + yyerror("invalid rdomain: %lld", $2); > + YYERROR; > + } > + vmc.vmc_ifflags[vcp_nnics] |= VMIFF_RDOMAIN; > + vmc.vmc_ifrdomain[vcp_nnics] = $2; > + } > | updown { > if ($1) > vmc.vmc_ifflags[vcp_nnics] |= VMIFF_UP; > @@ -645,6 +661,7 @@ lookup(char *s) > { "memory", MEMORY }, > { "owner", OWNER }, > { "prefix", PREFIX }, > + { "rdomain", RDOMAIN }, > { "size", SIZE }, > { "switch", SWITCH }, > { "up", UP }, > Index: usr.sbin/vmd/priv.c > =================================================================== > RCS file: /cvs/src/usr.sbin/vmd/priv.c,v > retrieving revision 1.8 > diff -u -p -u -p -r1.8 priv.c > --- usr.sbin/vmd/priv.c 21 Apr 2017 07:03:26 -0000 1.8 > +++ usr.sbin/vmd/priv.c 3 May 2017 10:02:59 -0000 > @@ -88,6 +88,7 @@ priv_dispatch_parent(int fd, struct priv > switch (imsg->hdr.type) { > case IMSG_VMDOP_PRIV_IFDESCR: > case IMSG_VMDOP_PRIV_IFCREATE: > + case IMSG_VMDOP_PRIV_IFRDOMAIN: > case IMSG_VMDOP_PRIV_IFADD: > case IMSG_VMDOP_PRIV_IFUP: > case IMSG_VMDOP_PRIV_IFDOWN: > @@ -124,6 +125,12 @@ priv_dispatch_parent(int fd, struct priv > errno != EEXIST) > log_warn("SIOCIFCREATE"); > break; > + case IMSG_VMDOP_PRIV_IFRDOMAIN: > + strlcpy(ifr.ifr_name, vfr.vfr_name, sizeof(ifr.ifr_name)); > + ifr.ifr_rdomainid = vfr.vfr_id; > + if (ioctl(env->vmd_fd, SIOCSIFRDOMAIN, &ifr) < 0) > + log_warn("SIOCSIFRDOMAIN"); > + break; > case IMSG_VMDOP_PRIV_IFADD: > if (priv_getiftype(vfr.vfr_value, type, NULL) == -1) > fatalx("%s: rejected to add interface: %s", > @@ -272,6 +279,17 @@ vm_priv_ifconfig(struct privsep *ps, str > sizeof(vfr.vfr_name)) >= sizeof(vfr.vfr_name)) > return (-1); > > + /* Set non-default rdomain */ > + if (vif->vif_flags & VMIFF_RDOMAIN) { > + vfr.vfr_id = vif->vif_rdomain; > + > + log_debug("%s: interface %s rdomain %u", __func__, > + vfr.vfr_name, vfr.vfr_id); > + > + proc_compose(ps, PROC_PRIV, IMSG_VMDOP_PRIV_IFRDOMAIN, > + &vfr, sizeof(vfr)); > + } > + > /* Description can be truncated */ > (void)snprintf(vfr.vfr_value, sizeof(vfr.vfr_value), > "vm%u-if%u-%s", vm->vm_vmid, i, vcp->vcp_name); > @@ -284,18 +302,25 @@ vm_priv_ifconfig(struct privsep *ps, str > > /* Add interface to bridge/switch */ > if ((vsw = switch_getbyname(vif->vif_switch)) != NULL) { > + memset(&vfbr, 0, sizeof(vfbr)); > + > if (strlcpy(vfbr.vfr_name, vsw->sw_ifname, > sizeof(vfbr.vfr_name)) >= sizeof(vfbr.vfr_name)) > return (-1); > if (strlcpy(vfbr.vfr_value, vif->vif_name, > sizeof(vfbr.vfr_value)) >= sizeof(vfbr.vfr_value)) > return (-1); > + vfbr.vfr_id = vsw->sw_rdomain; > > log_debug("%s: interface %s add %s", __func__, > vfbr.vfr_name, vfbr.vfr_value); > > proc_compose(ps, PROC_PRIV, IMSG_VMDOP_PRIV_IFCREATE, > &vfbr, sizeof(vfbr)); > + if (vsw->sw_flags & VMIFF_RDOMAIN) > + proc_compose(ps, > + PROC_PRIV, IMSG_VMDOP_PRIV_IFRDOMAIN, > + &vfbr, sizeof(vfbr)); > proc_compose(ps, PROC_PRIV, IMSG_VMDOP_PRIV_IFADD, > &vfbr, sizeof(vfbr)); > } else if (vif->vif_switch != NULL) > @@ -365,12 +390,20 @@ vm_priv_brconfig(struct privsep *ps, str > struct vmd_if *vif; > struct vmop_ifreq vfr; > > + memset(&vfr, 0, sizeof(vfr)); > + > if (strlcpy(vfr.vfr_name, vsw->sw_ifname, > sizeof(vfr.vfr_name)) >= sizeof(vfr.vfr_name)) > return (-1); > + vfr.vfr_id = vsw->sw_rdomain; > > proc_compose(ps, PROC_PRIV, IMSG_VMDOP_PRIV_IFCREATE, > &vfr, sizeof(vfr)); > + > + /* Set non-default rdomain */ > + if (vsw->sw_flags & VMIFF_RDOMAIN) > + proc_compose(ps, PROC_PRIV, IMSG_VMDOP_PRIV_IFRDOMAIN, > + &vfr, sizeof(vfr)); > > /* Description can be truncated */ > (void)snprintf(vfr.vfr_value, sizeof(vfr.vfr_value), > Index: usr.sbin/vmd/vm.conf.5 > =================================================================== > RCS file: /cvs/src/usr.sbin/vmd/vm.conf.5,v > retrieving revision 1.19 > diff -u -p -u -p -r1.19 vm.conf.5 > --- usr.sbin/vmd/vm.conf.5 21 Apr 2017 07:03:26 -0000 1.19 > +++ usr.sbin/vmd/vm.conf.5 3 May 2017 10:02:59 -0000 > @@ -161,6 +161,9 @@ If the > keyword is specified, > .Xr vmd 8 > will drop packets from the VM with altered source addresses. > +.It Cm rdomain Ar rdomainid > +Attach the interface to the routing domain with the specified > +.Ar rdomainid . > .It Cm switch Ar name > Set the virtual switch > by > @@ -282,6 +285,12 @@ e.g.\& > If the type is changed to > .Ar switch0 , > it will be used for each following switch. > +.It Cm rdomain Ar rdomainid > +Set the routing domain of the switch and all of its VM interfaces to > +.Ar rdomainid . > +This overwrites the > +.Cm rdomain > +option of VM interfaces. > .It Cm up > Start the switch forwarding packets. > This is the default. > Index: usr.sbin/vmd/vmd.c > =================================================================== > RCS file: /cvs/src/usr.sbin/vmd/vmd.c,v > retrieving revision 1.59 > diff -u -p -u -p -r1.59 vmd.c > --- usr.sbin/vmd/vmd.c 25 Apr 2017 16:38:23 -0000 1.59 > +++ usr.sbin/vmd/vmd.c 3 May 2017 10:02:59 -0000 > @@ -863,6 +863,10 @@ vm_register(struct privsep *ps, struct v > vm->vm_ifs[i].vif_fd = -1; > > if ((sw = switch_getbyname(vmc->vmc_ifswitch[i])) != NULL) { > + /* overwrite the rdomain; if configured on the switch */ > + if (sw->sw_flags & VMIFF_RDOMAIN) > + vmc->vmc_ifrdomain[i] = sw->sw_rdomain; > + > /* inherit per-interface flags from the switch */ > vmc->vmc_ifflags[i] |= (sw->sw_flags & VMIFF_OPTMASK); > } > Index: usr.sbin/vmd/vmd.h > =================================================================== > RCS file: /cvs/src/usr.sbin/vmd/vmd.h,v > retrieving revision 1.52 > diff -u -p -u -p -r1.52 vmd.h > --- usr.sbin/vmd/vmd.h 21 Apr 2017 07:03:26 -0000 1.52 > +++ usr.sbin/vmd/vmd.h 3 May 2017 10:02:59 -0000 > @@ -80,6 +80,7 @@ enum imsg_type { > IMSG_VMDOP_PRIV_IFDOWN, > IMSG_VMDOP_PRIV_IFGROUP, > IMSG_VMDOP_PRIV_IFADDR, > + IMSG_VMDOP_PRIV_IFRDOMAIN, > IMSG_VMDOP_VM_SHUTDOWN, > IMSG_VMDOP_VM_REBOOT, > IMSG_VMDOP_CONFIG > @@ -125,10 +126,12 @@ struct vmop_create_params { > #define VMIFF_UP 0x01 > #define VMIFF_LOCKED 0x02 > #define VMIFF_LOCAL 0x04 > -#define VMIFF_OPTMASK (VMIFF_LOCKED|VMIFF_LOCAL) > +#define VMIFF_RDOMAIN 0x08 > +#define VMIFF_OPTMASK (VMIFF_LOCKED|VMIFF_LOCAL|VMIFF_RDOMAIN) > char vmc_ifnames[VMM_MAX_NICS_PER_VM][IF_NAMESIZE]; > char vmc_ifswitch[VMM_MAX_NICS_PER_VM][VM_NAME_MAX]; > char vmc_ifgroup[VMM_MAX_NICS_PER_VM][IF_NAMESIZE]; > + unsigned int vmc_ifrdomain[VMM_MAX_NICS_PER_VM]; > uid_t vmc_uid; > int64_t vmc_gid; > }; > @@ -148,6 +151,7 @@ struct vmd_if { > char *vif_switch; > char *vif_group; > int vif_fd; > + unsigned int vif_rdomain; > unsigned int vif_flags; > TAILQ_ENTRY(vmd_if) vif_entry; > }; > @@ -158,6 +162,7 @@ struct vmd_switch { > char *sw_name; > char sw_ifname[IF_NAMESIZE]; > char *sw_group; > + unsigned int sw_rdomain; > unsigned int sw_flags; > struct viflist sw_ifs; > int sw_running; >