Skip to content

Instantly share code, notes, and snippets.

@ywh233
Last active September 18, 2020 01:05
Show Gist options
  • Save ywh233/214bbdaf06fc8c766ae4a84d816b4b33 to your computer and use it in GitHub Desktop.
Save ywh233/214bbdaf06fc8c766ae4a84d816b4b33 to your computer and use it in GitHub Desktop.
Patch mac80211 kernel module for libdrc
  1. Run uname -r to find your kernel's version number. It may return something like this:

    5.4.0-47-generic
    
  2. Run sudo apt install linux-source-$KERNEL_VERSION to grab the kernel code. $KERNEL_VERSION should be the X.X.X part of the version returned by uname -r, e.g. sudo apt install linux-source-5.4.0.

  3. Unzip /usr/src/linux-source-$KERNEL_VERSION/linux-source-$KERNEL_VERSION.tar.bz2.

  4. Go to net/mac80211 inside the unzipped folder, then apply this patch:

index 8d7747e..60094b6 100644
--- a/iface.c
+++ b/iface.c
@@ -1733,6 +1733,44 @@ static void ieee80211_assign_perm_addr(struct ieee80211_local *local,
 	mutex_unlock(&local->iflist_mtx);
 }
 
+static ssize_t ieee80211_tsf_show(struct device *dev, struct device_attribute *attr, char *buf) 
+{ 
+  struct net_device *ndev; 
+  struct ieee80211_sub_if_data *sdata; 
+  int need_remove = -1; 
+  u64 output = 0ULL; 
+ 
+  ndev = container_of(dev, struct net_device, dev); 
+ 
+  if(ndev == NULL) return -EIO; 
+ 
+  sdata = IEEE80211_DEV_TO_SUB_IF(ndev); 
+ 
+  if(sdata == NULL) return -EIO; 
+ 
+  if((sdata->flags & IEEE80211_SDATA_IN_DRIVER) == 0) 
+  { 
+    need_remove = drv_add_interface(sdata->local, sdata); 
+    if(need_remove != 0) 
+    { 
+      return -EIO; 
+    } 
+  } 
+ 
+  output = drv_get_tsf(sdata->local, sdata); 
+ 
+  if(need_remove == 0) // add earlier was needed and successful, so undo 
+  { 
+    drv_remove_interface(sdata->local, sdata); 
+  } 
+ 
+  memcpy(buf, &output, sizeof(u64)); 
+ 
+  return sizeof(u64); 
+} 
+ 
+DEVICE_ATTR(tsf, S_IRUGO, ieee80211_tsf_show, NULL );
+
 int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 		     unsigned char name_assign_type,
 		     struct wireless_dev **new_wdev, enum nl80211_iftype type,
@@ -1890,6 +1928,12 @@ int ieee80211_if_add(struct ieee80211_local *local, const char *name,
 			ieee80211_if_free(ndev);
 			return ret;
 		}
+		
+		ret = device_create_file(&ndev->dev, &dev_attr_tsf);
+		if(ret) {
+		  unregister_netdevice(ndev); // gets freed by destructor
+		  return ret;
+		}
 	}
 
 	mutex_lock(&local->iflist_mtx);
@@ -1913,6 +1957,7 @@ void ieee80211_if_remove(struct ieee80211_sub_if_data *sdata)
 	synchronize_rcu();
 
 	if (sdata->dev) {
+		device_remove_file(&sdata->dev->dev, &dev_attr_tsf);
 		unregister_netdevice(sdata->dev);
 	} else {
 		cfg80211_unregister_wdev(&sdata->wdev);
@@ -1956,8 +2001,10 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
 	list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
 		list_del(&sdata->list);
 
-		if (sdata->dev)
+		if (sdata->dev) {
+			device_remove_file(&sdata->dev->dev, &dev_attr_tsf);
 			unregister_netdevice_queue(sdata->dev, &unreg_list);
+		}
 		else
 			list_add(&sdata->list, &wdev_list);
 	}
  1. Run this:

    $ make -C /usr/src/linux-headers-$(uname -r) M=/path/to/your/kernel/code/net/mac80211
    $ sudo cp /lib/modules/$(uname -r)/kernel/net/mac80211/mac80211.ko /lib/modules/$(uname -r)/kernel/net/mac80211/mac80211.ko.bak
    $ sudo cp /path/to/your/kernel/code/net/mac80211 /lib/modules/$(uname -r)/kernel/net/mac80211/mac80211.ko
    
  2. Reboot your computer

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment