--atomic-commit should only try insmod when all else fails
diff --git a/communication.c b/communication.c
index ab21327..82888c0 100644
--- a/communication.c
+++ b/communication.c
@@ -263,10 +263,19 @@
 	/* give the data to the kernel */
 	optlen = sizeof(struct ebt_replace) + repl->entries_size;
 	get_sockfd();
-	if (setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen))
-		print_error("The kernel doesn't support a certain ebtables"
-		  " extension, consider recompiling your kernel or insmod"
-		  " the extension");
+	if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES, repl, optlen))
+		return;
+	if (u_repl->command == 8) { /* the ebtables module may not
+	                            * yet be loaded with --atomic-commit */
+		ebtables_insmod("ebtables");
+		if (!setsockopt(sockfd, IPPROTO_IP, EBT_SO_SET_ENTRIES,
+		    repl, optlen))
+			return;
+	}
+
+	print_error("The kernel doesn't support a certain ebtables"
+		    " extension, consider recompiling your kernel or insmod"
+		    " the extension");
 }
 
 static void store_counters_in_file(char *filename, struct ebt_u_replace *repl)
diff --git a/ebtables.c b/ebtables.c
index 29bccfe..27f2ff9 100644
--- a/ebtables.c
+++ b/ebtables.c
@@ -368,6 +368,7 @@
 	tables = t;
 }
 
+const char *modprobe = NULL;
 /*
  * blatently stolen (again) from iptables.c userspace program
  * find out where the modprobe utility is located
@@ -398,7 +399,7 @@
 	return NULL;
 }
 
-int ebtables_insmod(const char *modname, const char *modprobe)
+int ebtables_insmod(const char *modname)
 {
 	char *buf = NULL;
 	char *argv[3];
@@ -1593,7 +1594,7 @@
 	*flags |= mask;
 }
 
-static void get_kernel_table(const char *modprobe)
+static void get_kernel_table()
 {
 	if ( !(table = find_table(replace.name)) )
 		print_error("Bad table name");
@@ -1601,7 +1602,7 @@
 	 * get the kernel's information
 	 */
 	if (get_table(&replace)) {
-		ebtables_insmod("ebtables", modprobe);
+		ebtables_insmod("ebtables");
 		if (get_table(&replace))
 			print_error("The kernel doesn't support the ebtables "
 			"%s table", replace.name);
@@ -1645,7 +1646,6 @@
 	struct ebt_u_match_list *m_l;
 	struct ebt_u_watcher_list *w_l;
 	struct ebt_u_entries *entries;
-	const char *modprobe = NULL;
 
 	opterr = 0;
 
@@ -1691,7 +1691,7 @@
 			if (replace.flags & OPT_COMMAND)
 				print_error("Multiple commands not allowed");
 			replace.flags |= OPT_COMMAND;
-			get_kernel_table(modprobe);
+			get_kernel_table();
 			if (optarg[0] == '-' || !strcmp(optarg, "!"))
 				print_error("No chain name specified");
 			if (c == 'N') {
@@ -1831,7 +1831,7 @@
 					            " not allowed");
 				replace.flags |= OPT_COMMAND;
 			}
-			get_kernel_table(modprobe);
+			get_kernel_table();
 			i = -1;
 			if (optarg) {
 				if ( (i = get_hooknr(optarg)) == -1 )
@@ -2161,7 +2161,6 @@
 			 * possible memory leak here
 			 */
 			replace.filename = NULL;
-			ebtables_insmod("ebtables", modprobe);
 			break;
 		case 7 : /* atomic-init */
 		case 10: /* atomic-save */
@@ -2178,7 +2177,7 @@
 				tmp = replace.filename;
 				/* get the kernel table */
 				replace.filename = NULL;
-				get_kernel_table(modprobe);
+				get_kernel_table();
 				replace.filename = tmp;
 			}
 			if (replace.nentries) {
diff --git a/include/ebtables_u.h b/include/ebtables_u.h
index 741b00d..d17c4a4 100644
--- a/include/ebtables_u.h
+++ b/include/ebtables_u.h
@@ -210,6 +210,7 @@
 int check_inverse(const char option[]);
 void print_mac(const char *mac);
 void print_mac_and_mask(const char *mac, const char *mask);
+int ebtables_insmod(const char *modname);
 void __print_bug(char *file, int line, char *format, ...);
 #define print_bug(format, args...) \
    __print_bug(__FILE__, __LINE__, format, ##args)