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 19:04:22 +0300 [thread overview]
Message-ID: <20030818160422.GB1793@lapdog> (raw)
In-Reply-To: <20030818051227.4f35f2f3.davem@redhat.com>
On Mon, Aug 18, 2003 at 05:12:27AM -0700, David S. Miller wrote:
> There is another reason I want the cache flushed.
Alright, here's an implementation that does that.
Please comment.
A single flood ping from uml->host survives MAC
changes perfectly without dropping a single packet.
(Can't test realworld performance right now.)
Note I had to flush the route cache also, that was
tricking me previously. Clearing neigh_table isn't
enough, as the hh is reached from dst_entries also.
===== 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 18:51:40 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);
+ rt_cache_flush(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;
}
--
:(){ :|:&};:
next prev parent reply other threads:[~2003-08-18 16:04 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 [this message]
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=20030818160422.GB1793@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.