snd_seq_kernel_client_put(cptr);
 }
 
+/* set up client's group_filter bitmap */
+static void setup_client_group_filter(struct seq_ump_client *client)
+{
+       struct snd_seq_client *cptr;
+       unsigned int filter;
+       int p;
+
+       cptr = snd_seq_kernel_client_get(client->seq_client);
+       if (!cptr)
+               return;
+       filter = ~(1U << 0); /* always allow groupless messages */
+       for (p = 0; p < SNDRV_UMP_MAX_GROUPS; p++) {
+               if (client->groups[p].active)
+                       filter &= ~(1U << (p + 1));
+       }
+       cptr->group_filter = filter;
+       snd_seq_kernel_client_put(cptr);
+}
+
 /* UMP group change notification */
 static void handle_group_notify(struct work_struct *work)
 {
 
        update_group_attrs(client);
        update_port_infos(client);
+       setup_client_group_filter(client);
 }
 
 /* UMP FB change notification */
                        goto error;
        }
 
+       setup_client_group_filter(client);
+
        err = create_ump_endpoint_port(client);
        if (err < 0)
                goto error;
 
                           struct snd_seq_event *event,
                           int atomic, int hop)
 {
+       if (dest->group_filter & (1U << dest_port->ump_group))
+               return 0; /* group filtered - skip the event */
        if (event->type == SNDRV_SEQ_EVENT_SYSEX)
                return cvt_sysex_to_ump(dest, dest_port, event, atomic, hop);
        else if (snd_seq_client_is_midi2(dest))