From: Tommi Virtanen <tv@debian.org>
To: netdev@oss.sgi.com
Subject: [PATCH] Change MAC without bringing interface down
Date: Mon, 18 Aug 2003 12:13:12 +0300 [thread overview]
Message-ID: <20030818091312.GA4889@lapdog> (raw)
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);
}
--
:(){ :|:&};:
next reply other threads:[~2003-08-18 9:13 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2003-08-18 9:13 Tommi Virtanen [this message]
2003-08-18 11:19 ` [PATCH] Change MAC without bringing interface down 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
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20030818091312.GA4889@lapdog \
--to=tv@debian.org \
--cc=netdev@oss.sgi.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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).