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;
> 

Reply via email to