diff --git a/src/ndhc.h b/src/ndhc.h
index d231c55..bb20992 100644
--- a/src/ndhc.h
+++ b/src/ndhc.h
@@ -47,6 +47,7 @@ struct client_state_t {
     struct nk_random_state_u32 rnd32_state;
     uint8_t routerArp[6], serverArp[6];
     uint8_t using_dhcp_bpf, init, got_router_arp, got_server_arp;
+    uint8_t rfkill_set;
 };
 
 struct client_config_t {
diff --git a/src/netlink.c b/src/netlink.c
index f2ab2a3..b2d97df 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -48,6 +48,12 @@ static void nl_process_msgs(const struct nlmsghdr *nlh, void *data)
     struct ifinfomsg *ifm = NLMSG_DATA(nlh);
     struct client_state_t *cs = data;
 
+    // If the rfkill switch is set, a lot of netlink state change
+    // commands will fail outright, so just ignore events until
+    // it is gone.
+    if (cs->rfkill_set)
+        return;
+
     switch(nlh->nlmsg_type) {
         case RTM_NEWLINK:
             if (ifm->ifi_index != client_config.ifindex)
diff --git a/src/rfkill.c b/src/rfkill.c
index 4b2f703..57d0eb2 100644
--- a/src/rfkill.c
+++ b/src/rfkill.c
@@ -70,6 +70,7 @@ void handle_rfkill_notice(struct client_state_t cs[static 1], uint32_t rfkidx)
     if (event.op != RFKILL_OP_CHANGE && event.op != RFKILL_OP_CHANGE_ALL)
         return;
     if (event.soft || event.hard) {
+        cs->rfkill_set = 1;
         if (cs->ifsPrevState == IFS_UP) {
             log_line("rfkill: radio now blocked; bringing interface down");
             cs->ifsPrevState = IFS_DOWN;
@@ -77,6 +78,7 @@ void handle_rfkill_notice(struct client_state_t cs[static 1], uint32_t rfkidx)
         } else
             log_line("rfkill: radio now blocked, but interface isn't up");
     } else {
+        cs->rfkill_set = 0;
         if (cs->ifsPrevState == IFS_DOWN) {
             log_line("rfkill: radio now unblocked; bringing interface up");
             cs->ifsPrevState = IFS_UP;