netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] Change MAC without bringing interface down
@ 2003-08-18  9:13 Tommi Virtanen
  2003-08-18 11:19 ` David S. Miller
  0 siblings, 1 reply; 15+ messages in thread
From: Tommi Virtanen @ 2003-08-18  9:13 UTC (permalink / raw)
  To: netdev

	Hi. There are cases when you want to change your MAC address,
	such as in Linux-HA when the other box fails, and your hot
	standby activates itself.

	Some NICs, such as e100, e1000 and uml ;) allow you to do that
	without bringing the interface down. Which is nice, because it
	allows the link to stay up, and not make switches scratch their
	head for up to a minute.

	The problem is, if you do that, the old MAC address is stored
	in the hh_cache entries, and used in future traffic also.


	Here's a patch that

	1. makes eth_header_cache_update also update the source MAC in
	   hh_cache.

	2. adds a NETDEV_CHANGEADDR notifier in net/core/neighbour.c
	   that walks through all the neighbour entries and updates
	   the hh_cache's for all the neighbour entries related to
	   given device.

	3. adds neighbour_init() to allow registration of said notifier.


	Please comment.



===== include/net/neighbour.h 1.1 vs edited =====
--- 1.1/include/net/neighbour.h	Tue Feb  5 19:39:48 2002
+++ edited/include/net/neighbour.h	Mon Aug 18 11:17:25 2003
@@ -275,6 +275,8 @@
 	return neigh_create(tbl, pkey, dev);
 }
 
+extern void		neighbour_init(void);
+
 #endif
 #endif
 
===== net/core/dev.c 1.36 vs edited =====
--- 1.36/net/core/dev.c	Fri May 23 20:59:51 2003
+++ edited/net/core/dev.c	Mon Aug 18 11:54:30 2003
@@ -93,6 +93,7 @@
 #include <linux/if_bridge.h>
 #include <linux/divert.h>
 #include <net/dst.h>
+#include <net/neighbour.h>
 #include <net/pkt_sched.h>
 #include <net/profile.h>
 #include <net/checksum.h>
@@ -2849,6 +2850,7 @@
 	open_softirq(NET_RX_SOFTIRQ, net_rx_action, NULL);
 
 	dst_init();
+	neighbour_init();
 	dev_mcast_init();
 
 #ifdef CONFIG_NET_SCHED
===== net/core/neighbour.c 1.9 vs edited =====
--- 1.9/net/core/neighbour.c	Thu Jun 12 09:24:41 2003
+++ edited/net/core/neighbour.c	Mon Aug 18 11:53:50 2003
@@ -1558,3 +1558,46 @@
 }
 
 #endif	/* CONFIG_SYSCTL */
+
+static int neighbour_dev_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+
+	switch (event) {
+		struct neigh_table *tbl;
+	case NETDEV_CHANGEADDR:
+		read_lock(&neigh_tbl_lock);
+		for (tbl = neigh_tables; tbl; tbl=tbl->next) {
+			int i;
+
+			for (i=0; i<=NEIGH_HASHMASK; i++) {
+				struct neighbour *n, **np;
+
+				np = &tbl->hash_buckets[i];
+				write_lock(&tbl->lock);
+
+				while ((n = *np) != NULL) {
+					if (n->dev == dev) {
+						neigh_update_hhs(n);
+					}
+					np = &n->next;
+				}
+				write_unlock(&tbl->lock);
+			}
+		}
+		read_unlock(&neigh_tbl_lock);
+		break;
+	}
+	return NOTIFY_DONE;
+}
+
+struct notifier_block neighbour_dev_notifier = {
+	neighbour_dev_event,
+	NULL,
+	0
+};
+
+void __init neighbour_init(void)
+{
+	register_netdevice_notifier(&neighbour_dev_notifier);
+}
===== net/ethernet/eth.c 1.3 vs edited =====
--- 1.3/net/ethernet/eth.c	Fri Jun 20 00:22:53 2003
+++ edited/net/ethernet/eth.c	Mon Aug 18 11:55:36 2003
@@ -238,6 +238,11 @@
 
 void eth_header_cache_update(struct hh_cache *hh, struct net_device *dev, unsigned char * haddr)
 {
-	memcpy(((u8*)hh->hh_data) + HH_DATA_OFF(sizeof(struct ethhdr)),
-	       haddr, dev->addr_len);
+	struct ethhdr *eth;
+
+	eth = (struct ethhdr*)
+		(((u8*)hh->hh_data) + (HH_DATA_OFF(sizeof(*eth))));
+
+	memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
+	memcpy(eth->h_dest, haddr, dev->addr_len);
 }


-- 
:(){ :|:&};:

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2003-08-19 19:31 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2003-08-18  9:13 [PATCH] Change MAC without bringing interface down Tommi Virtanen
2003-08-18 11:19 ` David S. Miller
2003-08-18 12:13   ` jamal
2003-08-18 12:12     ` David S. Miller
2003-08-18 13:03       ` jamal
2003-08-18 16:04       ` Tommi Virtanen
2003-08-18 16:06         ` David S. Miller
2003-08-18 17:11           ` Tommi Virtanen
2003-08-18 18:51             ` Arnaldo Carvalho de Melo
2003-08-19  5:50               ` Tommi Virtanen
2003-08-19 15:42                 ` Arnaldo Carvalho de Melo
2003-08-19 19:31                 ` David S. Miller
2003-08-18 14:24   ` Tommi Virtanen
2003-08-18 14:20     ` David S. Miller
2003-08-18 15:10     ` jamal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).