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?

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