Skip to contentSkip to conversation

Use prinkt instead of debug_log

B.A.T.M.A.N. Andrew Lunn 2 participants 6 messages Aug 23, 2009 – Aug 24, 2009

lore
Share & tools
lore
#0 lore raw

If batman is to get into mainline, the use of debug_log will need to be removed. This is a first step in this direction. It replaces debug_log calls for CRITICAL, WARNING and NOTICE with printk calls. It tries to consistently prefix all such output with "batman:" making it easier to find such output mixed in with other kernel messages. LOG_TYPE_BATMAN and LOG_TYPE_ROUTES has not been changed.

vis.c +6 -6
Index: batman-adv-kernelland/vis.c
===================================================================
@@ -440,8 +440,8 @@
 	int packet_length;
 
 	if (info->packet.ttl < 2) {
-		debug_log(LOG_TYPE_NOTICE,
-			  "Error - can't send vis packet: ttl exceeded\n");
+		printk(KERN_DEBUG
+			  "batman: Can't send vis packet: ttl exceeded\n");
 		return;
 	}
 
@@ -490,13 +490,13 @@
 
 	vis_hash = hash_new(256, vis_info_cmp, vis_info_choose);
 	if (!vis_hash) {
-		debug_log(LOG_TYPE_CRIT, "Can't initialize vis_hash\n");
+		printk(KERN_ERR  "batman: Can't initialize vis_hash\n");
 		goto err;
 	}
 
 	my_vis_info = kmalloc(1000, GFP_KERNEL);
 	if (!my_vis_info) {
-		debug_log(LOG_TYPE_CRIT, "Can't initialize vis packet\n");
+		printk(KERN_ERR  "batman: Can't initialize vis packet\n");
 		goto err;
 	}
 
@@ -517,8 +517,8 @@
 	memcpy(my_vis_info->packet.sender_orig, mainIfAddr, ETH_ALEN);
 
 	if (hash_add(vis_hash, my_vis_info) < 0) {
-		debug_log(LOG_TYPE_CRIT,
-			  "Can't add own vis packet into hash\n");
+		printk(KERN_ERR
+			  "batman: Can't add own vis packet into hash\n");
 		free_info(my_vis_info);	/* not in hash, need to remove it
 					 * manually. */
 		goto err;
translation-table.c +2 -2
Index: batman-adv-kernelland/translation-table.c
===================================================================
@@ -111,7 +111,7 @@
 				       hna_local_hash->size * 2);
 
 		if (swaphash == NULL)
-			debug_log(LOG_TYPE_CRIT, "Couldn't resize local hna hash table \n");
+			printk(KERN_ERR "batman: Couldn't resize local hna hash table \n");
 		else
 			hna_local_hash = swaphash;
 	}
@@ -331,7 +331,7 @@
 				       hna_global_hash->size * 2);
 
 		if (swaphash == NULL)
-			debug_log(LOG_TYPE_CRIT, "Couldn't resize global hna hash table \n");
+			printk(KERN_ERR "batman: Couldn't resize global hna hash table \n");
 		else
 			hna_global_hash = swaphash;
 	}
send.c +5 -5
Index: batman-adv-kernelland/send.c
===================================================================
@@ -70,8 +70,8 @@
 		return;
 
 	if (!(batman_if->net_dev->flags & IFF_UP)) {
-		debug_log(LOG_TYPE_WARN,
-			  "Interface %s is not up - can't send packet via that interface !\n", batman_if->dev);
+		printk(KERN_WARNING
+		       "batman: Interface %s is not up - can't send packet via that interface !\n", batman_if->dev);
 		batman_if->if_active = IF_TO_BE_DEACTIVATED;
 		return;
 	}
@@ -99,7 +99,7 @@
 	 * (which is > 0). This will not be treated as an error. */
 	retval = dev_queue_xmit(skb);
 	if (retval < 0) {
-		debug_log(LOG_TYPE_CRIT, "Can't write to raw socket: %i\n",
+		printk(KERN_WARNING "batman: Can't write to raw socket: %i\n",
 			  retval);
 		batman_if->if_active = IF_TO_BE_DEACTIVATED;
 	}
@@ -171,8 +171,8 @@
 	unsigned char directlink = (batman_packet->flags & DIRECTLINK ? 1 : 0);
 
 	if (!forw_packet->if_incoming) {
-		debug_log(LOG_TYPE_CRIT,
-			  "Error - can't forward packet: incoming iface not specified\n");
+		printk(KERN_ERR
+			  "batman: Can't forward packet: incoming iface not specified\n");
 		return;
 	}
 
device.c +8 -8
Index: batman-adv-kernelland/device.c
===================================================================
@@ -60,7 +60,7 @@
 	/* register our device - kernel assigns a free major number */
 	tmp_major = register_chrdev(0, DRIVER_DEVICE, &fops);
 	if (tmp_major < 0) {
-		debug_log(LOG_TYPE_WARN, "Registering the character device failed with %d\n",
+		printk(KERN_ERR "batman: Registering the character device failed with %d\n",
 			  tmp_major);
 		return 0;
 	}
@@ -68,14 +68,14 @@
 #if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0)
 	if (devfs_mk_cdev(MKDEV(tmp_major, 0), S_IFCHR | S_IRUGO | S_IWUGO,
 			  "batman-adv", 0)) {
-		debug_log(LOG_TYPE_WARN, "Could not create /dev/batman-adv\n");
+		printk(KERN_ERR "batman: Could not create /dev/batman-adv\n");
 		return 0;
 	}
 #else
 	batman_class = class_create(THIS_MODULE, "batman-adv");
 
 	if (IS_ERR(batman_class)) {
-		debug_log(LOG_TYPE_WARN, "Could not register class 'batman-adv' \n");
+		printk(KERN_ERR "batman: Could not register class 'batman-adv' \n");
 		return 0;
 	}
 
@@ -109,7 +109,7 @@
 #endif
 
 	if (result < 0)
-		debug_log(LOG_TYPE_WARN, "Unregistering the character device failed with %d\n", result);
+		printk(KERN_ERR "batman: Unregistering the character device failed with %d\n", result);
 
 	Major = 0;
 }
@@ -132,7 +132,7 @@
 	}
 
 	if (device_client_hash[i] != device_client) {
-		debug_log(LOG_TYPE_WARN, "Error - can't add another packet client: maximum number of clients reached \n");
+		printk(KERN_INFO "batman: Can't add another packet client: maximum number of clients reached \n");
 		kfree(device_client);
 		return -EXFULL;
 	}
@@ -229,7 +229,7 @@
 	struct batman_if *batman_if;
 
 	if (len < sizeof(struct icmp_packet)) {
-		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: invalid packet size\n");
+		printk(KERN_DEBUG "batman: Can't send packet from char device: invalid packet size\n");
 		return -EINVAL;
 	}
 
@@ -240,12 +240,12 @@
 		return -EFAULT;
 
 	if (icmp_packet.packet_type != BAT_ICMP) {
-		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
+		printk(KERN_DEBUG "batman: Can't send packet from char device: got bogus packet type (expected: BAT_ICMP)\n");
 		return -EINVAL;
 	}
 
 	if (icmp_packet.msg_type != ECHO_REQUEST) {
-		debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
+		printk(KERN_DEBUG "batman: Can't send packet from char device: got bogus message type (expected: ECHO_REQUEST)\n");
 		return -EINVAL;
 	}
 
proc.c +29 -40

211 lines not on this page · raw message

soft-interface.c +1 -1
Index: batman-adv-kernelland/soft-interface.c
===================================================================
@@ -212,7 +212,7 @@
 		 * dropping */
 		if (!spin_trylock(&orig_hash_lock)) {
 			lock_dropped++;
-			debug_log(LOG_TYPE_NOTICE, "%d packets dropped because lock was hold\n", lock_dropped);
+			printk(KERN_DEBUG "batman: %d packets dropped because lock was hold\n", lock_dropped);
 			goto dropped;
 		}
 
hard-interface.c +11 -11
Index: batman-adv-kernelland/hard-interface.c
===================================================================
@@ -119,7 +119,7 @@
 	batman_if->if_active = IF_INACTIVE;
 	active_ifs--;
 
-	debug_log(LOG_TYPE_NOTICE, "Interface deactivated: %s\n",
+	printk(KERN_INFO "batman: Interface deactivated: %s\n",
 		  batman_if->dev);
 }
 
@@ -142,8 +142,8 @@
 				  &batman_if->raw_sock);
 
 	if (retval < 0) {
-		debug_log(LOG_TYPE_WARN, "Can't create raw socket: %i\n",
-			  retval);
+		printk(KERN_ERR "batman: Can't create raw socket: %i\n",
+		       retval);
 		goto error;
 	}
 
@@ -155,8 +155,8 @@
 			     (struct sockaddr *)&bind_addr, sizeof(bind_addr));
 
 	if (retval < 0) {
-		debug_log(LOG_TYPE_WARN, "Can't create bind raw socket: %i\n",
-			  retval);
+		printk(KERN_ERR "batman: Can't create bind raw socket: %i\n",
+		       retval);
 		goto error;
 	}
 
@@ -225,7 +225,7 @@
 	data_ptr = kmalloc((if_num + 1) * sizeof(TYPE_OF_WORD) * NUM_WORDS,
 			   GFP_ATOMIC);
 	if (!data_ptr) {
-		debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+		printk(KERN_WARNING "batman: Can't resize orig: out of memory\n");
 		return -1;
 	}
 
@@ -236,7 +236,7 @@
 
 	data_ptr = kmalloc((if_num + 1) * sizeof(uint8_t), GFP_ATOMIC);
 	if (!data_ptr) {
-		debug_log(LOG_TYPE_WARN, "Can't resize orig: out of memory\n");
+		printk(KERN_WARNING "batman: Can't resize orig: out of memory\n");
 		return -1;
 	}
 
@@ -259,7 +259,7 @@
 	batman_if = kmalloc(sizeof(struct batman_if), GFP_KERNEL);
 
 	if (!batman_if) {
-		debug_log(LOG_TYPE_WARN, "Can't add interface (%s): out of memory\n", dev);
+		printk(KERN_WARNING "batman: Can't add interface (%s): out of memory\n", dev);
 		return -1;
 	}
 
@@ -274,7 +274,7 @@
 	batman_if->packet_buff = kmalloc(batman_if->packet_len, GFP_KERNEL);
 
 	if (!batman_if->packet_buff) {
-		debug_log(LOG_TYPE_WARN, "Can't add interface packet (%s): out of memory\n", dev);
+		printk(KERN_WARNING "batman: Can't add interface packet (%s): out of memory\n", dev);
 		goto out;
 	}
 
@@ -283,7 +283,7 @@
 	batman_if->if_active = IF_INACTIVE;
 	INIT_RCU_HEAD(&batman_if->rcu);
 
-	debug_log(LOG_TYPE_NOTICE, "Adding interface: %s\n", dev);
+	printk(KERN_INFO "batman: Adding interface: %s\n", dev);
 	avail_ifs++;
 
 	INIT_LIST_HEAD(&batman_if->list);
@@ -324,7 +324,7 @@
 	spin_unlock(&orig_hash_lock);
 
 	if (!hardif_is_interface_up(batman_if->dev))
-		debug_log(LOG_TYPE_WARN, "Not using interface %s (retrying later): interface not active\n", batman_if->dev);
+		printk(KERN_WARNING "batman: Not using interface %s (retrying later): interface not active\n", batman_if->dev);
 
 	list_add_tail_rcu(&batman_if->list, &if_list);
 
log.c +1 -9
Index: batman-adv-kernelland/log.c
===================================================================
@@ -80,17 +80,9 @@
 	int retval = 0;
 	char tmp_log_buf[256];
 
-	/* only critical information get into the official kernel log */
-	if (type == LOG_TYPE_CRIT) {
+	if (log_level & type) {
 		va_start(args, fmt);
 		vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
-		printk(KERN_ERR "batman-adv: %s", tmp_log_buf);
-		va_end(args);
-	}
-
-	if ((type == LOG_TYPE_CRIT) || (log_level & type)) {
-		va_start(args, fmt);
-		vscnprintf(tmp_log_buf, sizeof(tmp_log_buf), fmt, args);
 		fdebug_log("[%10u] %s", (jiffies / HZ), tmp_log_buf);
 		va_end(args);
 	}
main.c +5 -5
Index: batman-adv-kernelland/main.c
===================================================================
@@ -88,20 +88,20 @@
 				   interface_setup);
 
 	if (!soft_device) {
-		debug_log(LOG_TYPE_CRIT, "Unable to allocate the batman interface\n");
+		printk(KERN_ERR "batman: Unable to allocate the batman interface\n");
 		goto end;
 	}
 
 	retval = register_netdev(soft_device);
 
 	if (retval < 0) {
-		debug_log(LOG_TYPE_CRIT, "Unable to register the batman interface: %i\n", retval);
+		printk(KERN_ERR  "batman: Unable to register the batman interface: %i\n", retval);
 		goto free_soft_device;
 	}
 
 	start_hardif_check_timer();
 
-	debug_log(LOG_TYPE_CRIT, "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
+	printk(KERN_INFO  "B.A.T.M.A.N. advanced %s%s (compatibility version %i) loaded \n",
 	          SOURCE_VERSION, REVISION_VERSION_STR, COMPAT_VERSION);
 
 	return 0;
@@ -154,7 +154,7 @@
 		kthread_task = kthread_run(packet_recv_thread, NULL, "batman-adv");
 
 		if (IS_ERR(kthread_task)) {
-			debug_log(LOG_TYPE_CRIT, "Unable to start packet receive thread\n");
+			printk(KERN_ERR  "batman: Unable to start packet receive thread\n");
 			kthread_task = NULL;
 		}
 	}
@@ -163,7 +163,7 @@
 	goto end;
 
 err:
-	debug_log(LOG_TYPE_CRIT, "Unable to allocate memory for mesh information structures: out of mem ?\n");
+	printk(KERN_ERR  "batman: Unable to allocate memory for mesh information structures: out of mem ?\n");
 	shutdown_module();
 end:
 	return;
routing.c +9 -8
Index: batman-adv-kernelland/routing.c
===================================================================
@@ -156,7 +156,7 @@
 		swaphash = hash_resize(orig_hash, orig_hash->size * 2);
 
 		if (swaphash == NULL)
-			debug_log(LOG_TYPE_CRIT, "Couldn't resize orig hash table \n");
+			printk(KERN_WARNING "batman: Couldn't resize orig hash table \n");
 		else
 			orig_hash = swaphash;
 	}
@@ -617,7 +617,7 @@
 	atomic_set(&exit_cond, 0);
 	packet_buff = kmalloc(PACKBUFF_SIZE, GFP_KERNEL);
 	if (!packet_buff) {
-		debug_log(LOG_TYPE_CRIT, "Could allocate memory for the packet buffer. :(\n");
+		printk(KERN_ERR "batman: Couldn't allocate memory for the packet buffer. :(\n");
 		return -1;
 	}
 
@@ -640,8 +640,8 @@
 			while (1) {
 				if (batman_if->if_active != IF_ACTIVE) {
 					if (batman_if->if_active != IF_TO_BE_ACTIVATED)
-						debug_log(LOG_TYPE_NOTICE,
-						          "Could not read from deactivated interface %s!\n",
+						printk(KERN_DEBUG
+						       "batman: Could not read from deactivated interface %s!\n",
 						          batman_if->dev);
 
 					if (batman_if->raw_sock)
@@ -748,7 +748,7 @@
 						addr_to_string(src_str, icmp_packet->orig);
 						addr_to_string(dst_str, icmp_packet->dst);
 
-						debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
+						printk(KERN_DEBUG "batman: Can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
 
 						/* send TTL exceeded if packet is an echo request (traceroute) */
 						if (icmp_packet->msg_type != ECHO_REQUEST)
@@ -829,7 +829,7 @@
 						addr_to_string(src_str, ((struct ethhdr *)(unicast_packet + 1))->h_source);
 						addr_to_string(dst_str, unicast_packet->dest);
 
-						debug_log(LOG_TYPE_NOTICE, "Error - can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
+						printk(KERN_DEBUG "batman: Can't send packet from %s to %s: ttl exceeded\n", src_str, dst_str);
 						continue;
 					}
 
@@ -942,8 +942,9 @@
 
 			}
 
-			if ((result < 0) && (result != -EAGAIN))
-				debug_log(LOG_TYPE_CRIT, "Could not receive packet from interface %s: %i\n", batman_if->dev, result);
+			if ((result < 0) && (result != -EAGAIN) &&
+			    printk_ratelimit())
+				printk(KERN_WARNING "batman: Could not receive packet from interface %s: %i\n", batman_if->dev, result);
 
 			/* lock for the next iteration */
 			rcu_read_lock();
main.h +0 -10
Index: batman-adv-kernelland/main.h
===================================================================
@@ -66,19 +66,9 @@
  * Logging
  */
 
-#define LOG_TYPE_CRIT 0		/* highest priority for fatal errors such as
-				 * blocked sockets / failed packet delivery /
-				 * programming errors */
-#define LOG_TYPE_WARN 1		/* warnings for small errors like wrong user
-				 * input / damaged packets / etc */
-#define LOG_TYPE_NOTICE 2	/* notice information for new interfaces /
-				 * changed settings / new originators / etc */
 #define LOG_TYPE_BATMAN 4	/* all messages related to routing / flooding /
 				 * broadcasting / etc */
 #define LOG_TYPE_ROUTES 8	/* route or hna added / changed / deleted */
-#define LOG_TYPE_CRIT_NAME	"critical"
-#define LOG_TYPE_WARN_NAME	"warnings"
-#define LOG_TYPE_NOTICE_NAME	"notices"
 #define LOG_TYPE_BATMAN_NAME	"batman"
 #define LOG_TYPE_ROUTES_NAME	"routes"
 
#1 lore raw

Hi Folks

I've been considering what to do with the remaining debug_log calls.

We have three classes of output from debug_log:

1) Changes to HNA entries, all in translation-table.c.
2) Changes of routes, all in routing.c
3) All the remaining debug output scattered in a number of files.

1) and 2) are pretty low volume in terms of output, and code size.

3) is a lot more verbose and needs more code. It is also not so efficient in that it does lots of string manipulations, creating ascii representations of MAC addresses which rarely get output. That can be fixed once we are close to integration to mainline and can drop backward compatibility to older kernels. We can then use the %pM format in printk. However, until then, it would be good to be able to compile out this code.

Traditionally the network code uses pr_debug() for outputting debug information. This is disabled by default and in order to see it, it is necessary to add #define DEBUG to any file you want to see the debug output from.

I don't think pr_debug is flexible enough for what we want at the moment. My proposal is to add to main.h macros

#define CONFIG_BATMAN_DEBUG_ROUTE 1
#define CONFIG_BATMAN_DEBUG_BATMAN 0

#if CONFIG_BATMAN_DEBUG_ROUTE
pr_route_debug(format, a...) printk(KERN_DEBUG "batman:" format, ##a) #else
pr_route_debug(format, a...)
#endif

#if CONFIG_BATMAN_DEBUG_BATMAN
pr_batman_debug(format, a...) printk(KERN_DEBUG "batman:" format, ##a) #else
pr_batman_debug(format, a...)
#endif

So by default the routing updates will make it out, but the rest is disabled by default.

What do others think?

Andrew

#2 lore raw
In reply to Andrew Lunn

Hey,

Quoted 6 lines

If batman is to get into mainline, the use of debug_log will need to be removed. This is a first step in this direction. It replaces debug_log calls for CRITICAL, WARNING and NOTICE with printk calls. It tries to consistently prefix all such output with "batman:" making it easier to find such output mixed in with other kernel messages. LOG_TYPE_BATMAN and LOG_TYPE_ROUTES has not been changed.

thanks a lot for your patch and thoughts.
Does this patch mean you got in touch with a maintainer and he/she suggested to do that ? What else did he/she suggest ?
I'm asking because I want to understand in which direction we are moving before I start rowing. ;-)

Regards,
Marek

#3 lore raw
Quoted 2 lines

Does this patch mean you got in touch with a maintainer and he/she suggested to do that ? What else did he/she suggest ?

No i've not asked yet. However, i don't know of any other kernel module which does debug output in a similar way. So my guess is this needs changing.

I keep intending to make a ToDo list. Here is what i have in my mind at the moment. Some are just questions/ideas and all of it needs discussing.

Finish stripping out debug_log.

Make batctl standalone.

Maybe make batctl _The_ tool for configuration and status and depreciate direct proc access, so that we can restructure it without too much pain for users.

Take out the dot_draw/josm formatting in vis and put it into batctl.

Think if /proc/net/batman-adv should be renamed /proc/net/bat0 giving the option of /proc/net/bat1 etc in the future?

Should /proc/net/batman-adv/interface be replaced with an IOCTL interface similar to brctl?

Maybe move orig_interval, aggregate_ogm and write half of vis to /sys? At least spit vis into two.

Investigate if there is a generic linux hash algorithm which should be used?

Strip out all backward compatibility support.

Make use of printk %pM support.

Andrew

#4 lore raw
Quoted 7 lines · On Monday 24 August 2009 18:08:17 Andrew Lunn wrote:

No i've not asked yet. However, i don't know of any other kernel module which does debug output in a similar way. So my guess is this needs changing.

I keep intending to make a ToDo list. Here is what i have in my mind at the moment. Some are just questions/ideas and all of it needs discussing.

I also believe that the logging probably needs to be reworked as well as other things. But I'd rather check with some kernel maintainers first before we start a bigger rework process based on assumptions. Maybe they tell us that this module will never be included because they don't think this is the way to do it.

The todo list is a great start. I imagine it could help us when we talk to the maintainers.

Quoted 1 line

Finish stripping out debug_log.

Probably ok but how do we handle the routing protocol debugging stuff ? Should we pipe everything through printk ? Actually, that considerably slows down the system because many distros write that into a log file.

Quoted 1 line

Make batctl standalone.

What does that mean ?

Quoted 3 lines

Maybe make batctl _The_ tool for configuration and status and depreciate direct proc access, so that we can restructure it without too much pain for users.

Handling everything via ioctls ?

Quoted 11 lines

Take out the dot_draw/josm formatting in vis and put it into batctl.

Think if /proc/net/batman-adv should be renamed /proc/net/bat0 giving the option of /proc/net/bat1 etc in the future?

Should /proc/net/batman-adv/interface be replaced with an IOCTL interface similar to brctl?

Maybe move orig_interval, aggregate_ogm and write half of vis to /sys? At least spit vis into two.

Quoted 6 lines

Investigate if there is a generic linux hash algorithm which should be used?

Strip out all backward compatibility support.

Make use of printk %pM support.

Sounds like a good list.

Regards,
Marek

#5 lore raw
Quoted 6 lines
Quoted 1 line

Finish stripping out debug_log.

Probably ok but how do we handle the routing protocol debugging stuff ? Should we pipe everything through printk ? Actually, that considerably slows down the system because many distros write that into a log file.

By default, it would be disabled, at compile time. So for 99% of users, there is in fact a speedup. Anybody who needs the debug info would have to recompile the module. Or there are more options. eg The code is always compiled by default, but needs a module option to actually enable the output. For those wanting a lean/mean system, the code can be compile out, etc.

Quoted 3 lines
Quoted 1 line

Make batctl standalone.

What does that mean ?

At the moment, to use batman-adv you need the source to batman, layer-3, user space daemon in order to get batctl to compile. There are symbolic links for hash.[ch] and list-batman.[ch]. To the kernel folks, this dependency will seem a little odd.

Quoted 5 lines
Quoted 3 lines

Maybe make batctl _The_ tool for configuration and status and depreciate direct proc access, so that we can restructure it without too much pain for users.

Handling everything via ioctls ?

That is probably too far. I would probably keep /proc/net/bat0/[originators|transtable_global|transtable_local|vis].

where vis contains the actual data.

and create

/sys/class/batman/bat0/[aggregate_ogm|orig_interval|vis]

and here vis controls server/client functionality. Maybe it needs a different name?

As for configuring interfaces, maybe in the long terms we should be thinking of commands like:

batctl add bat0
batclt addif bat0 eth1
batclt addif bat0 wlan1

batctl delif bat0 eth1
batctl delif bat0 wlan1
batctl del bat0

The first implementation of this would use interfaces in proc. Once the ioctl calls are implemented, you then need a new version of batctl which uses them. To the user it stay the same.

Probably the first version would not even support bat1. It is an interesting question if supporting multiple batman instances is needed. There could be two overlapping meshs in different administrative domains. Or maybe in a high redundancy situation, you run two separate meshes, and duplicate packets to both meshs and filter out duplicates at the other end. So maybe there are uses?

Andrew