All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tommi Virtanen <tv@debian.org>
To: "David S. Miller" <davem@redhat.com>
Cc: hadi@cyberus.ca, netdev@oss.sgi.com
Subject: Re: [PATCH] Change MAC without bringing interface down
Date: Mon, 18 Aug 2003 20:11:44 +0300	[thread overview]
Message-ID: <20030818171144.GC1793@lapdog> (raw)
In-Reply-To: <20030818090654.7f44a16e.davem@redhat.com>

On Mon, Aug 18, 2003 at 09:06:54AM -0700, David S. Miller wrote:
> > ===== net/ipv6/ndisc.c 1.22 vs edited =====
> > --- 1.22/net/ipv6/ndisc.c	Tue Jun 24 02:21:28 2003
> > +++ edited/net/ipv6/ndisc.c	Mon Aug 18 18:51:40 2003
>  ...
> > +	case NETDEV_CHANGEADDR:
> > +		neigh_changeaddr(&nd_tbl, dev);
> > +		rt_cache_flush(0);
> 
> Don't flush the ipv4 routing cache from ipv6 please :-)

	Good point.

	I don't have an IPv6 test setup, so that side is..
	umm.. improvised ;)

	Here's the updated patch; I feel this is suitable for
	inclusion, performance can always be improved; remember, the
	current situation is either 10s..1min of no traffic passing
	because you had to bring down the interface, or cache lifetime
	of existing flows using the old MAC. This is a whole lot
	better.

===== 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 18:52:30 2003
@@ -180,6 +180,7 @@
 extern void			neigh_destroy(struct neighbour *neigh);
 extern int			__neigh_event_send(struct neighbour *neigh, struct sk_buff *skb);
 extern int			neigh_update(struct neighbour *neigh, const u8 *lladdr, u8 new, int override, int arp);
+extern void			neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 extern int			neigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
 extern int			neigh_resolve_output(struct sk_buff *skb);
 extern int			neigh_connected_output(struct sk_buff *skb);
===== 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 18:52:41 2003
@@ -50,6 +50,7 @@
 static void neigh_app_notify(struct neighbour *n);
 #endif
 static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
+void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 
 static int neigh_glbl_allocs;
 static struct neigh_table *neigh_tables;
@@ -167,6 +168,33 @@
 		dev_put(skb->dev);
 		kfree_skb(skb);
 	}
+}
+
+void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev)
+{
+	int i;
+
+	write_lock_bh(&tbl->lock);
+
+	for (i=0; i<=NEIGH_HASHMASK; i++) {
+		struct neighbour *n, **np;
+
+		np = &tbl->hash_buckets[i];
+		while ((n = *np) != NULL) {
+			if (dev && n->dev != dev) {
+				np = &n->next;
+				continue;
+			}
+			*np = n->next;
+			write_lock_bh(&n->lock);
+			n->dead = 1;
+			neigh_del_timer(n);
+			write_unlock_bh(&n->lock);
+			neigh_release(n);
+		}
+	}
+
+        write_unlock_bh(&tbl->lock);
 }
 
 int neigh_ifdown(struct neigh_table *tbl, struct net_device *dev)
===== net/ipv4/arp.c 1.11 vs edited =====
--- 1.11/net/ipv4/arp.c	Fri Jun 27 09:03:01 2003
+++ edited/net/ipv4/arp.c	Mon Aug 18 18:51:10 2003
@@ -1212,6 +1212,28 @@
 }
 #endif
 
+static int arp_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+
+	switch (event) {
+	case NETDEV_CHANGEADDR:
+		neigh_changeaddr(&arp_tbl, dev);
+		rt_cache_flush(0);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+struct notifier_block arp_netdev_notifier = {
+	arp_netdev_event,
+	NULL,
+	0
+};
+
 /* Note, that it is not on notifier chain.
    It is necessary, that this routine was called after route cache will be
    flushed.
@@ -1243,6 +1265,7 @@
 #ifdef CONFIG_SYSCTL
 	neigh_sysctl_register(NULL, &arp_tbl.parms, NET_IPV4, NET_IPV4_NEIGH, "ipv4");
 #endif
+	register_netdevice_notifier(&arp_netdev_notifier);
 }
 
 
===== net/ipv6/ndisc.c 1.22 vs edited =====
--- 1.22/net/ipv6/ndisc.c	Tue Jun 24 02:21:28 2003
+++ edited/net/ipv6/ndisc.c	Mon Aug 18 20:06:11 2003
@@ -1336,6 +1336,28 @@
 	return 0;
 }
 
+static int ndisc_netdev_event(struct notifier_block *this, unsigned long event, void *ptr)
+{
+	struct net_device *dev = ptr;
+
+	switch (event) {
+	case NETDEV_CHANGEADDR:
+		neigh_changeaddr(&nd_tbl, dev);
+		fib6_run_gc(0);
+		break;
+	default:
+		break;
+	}
+
+	return NOTIFY_DONE;
+}
+
+struct notifier_block ndisc_netdev_notifier = {
+	ndisc_netdev_event,
+	NULL,
+	0
+};
+
 int __init ndisc_init(struct net_proto_family *ops)
 {
 	struct sock *sk;
@@ -1377,6 +1399,7 @@
 	neigh_sysctl_register(NULL, &nd_tbl.parms, NET_IPV6, NET_IPV6_NEIGH, "ipv6");
 #endif
 
+	register_netdevice_notifier(&ndisc_netdev_notifier);
 	return 0;
 }
 


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

  reply	other threads:[~2003-08-18 17:11 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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=20030818171144.GC1793@lapdog \
    --to=tv@debian.org \
    --cc=davem@redhat.com \
    --cc=hadi@cyberus.ca \
    --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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.