Skip to content

Commit

Permalink
gre: Fix dev_addr clobbering for gretap
Browse files Browse the repository at this point in the history
Nathan Neulinger noticed that gretap devices get their MAC address
from the local IP address, which results in invalid MAC addresses
half of the time.

This is because gretap is still using the tunnel netdev ops rather
than the correct tap netdev ops struct.

This patch also fixes changelink to not clobber the MAC address
for the gretap case.

Signed-off-by: Herbert Xu <[email protected]>
Acked-by: Stephen Hemminger <[email protected]>
Tested-by: Nathan Neulinger <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
herbertx authored and davem330 committed Oct 30, 2009
1 parent 33cb7d3 commit 2e9526b
Showing 1 changed file with 16 additions and 12 deletions.
28 changes: 16 additions & 12 deletions net/ipv4/ip_gre.c
Original file line number Diff line number Diff line change
Expand Up @@ -1464,7 +1464,7 @@ static void ipgre_tap_setup(struct net_device *dev)

ether_setup(dev);

dev->netdev_ops = &ipgre_netdev_ops;
dev->netdev_ops = &ipgre_tap_netdev_ops;
dev->destructor = free_netdev;

dev->iflink = 0;
Expand Down Expand Up @@ -1525,25 +1525,29 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[],
if (t->dev != dev)
return -EEXIST;
} else {
unsigned nflags = 0;

t = nt;

if (ipv4_is_multicast(p.iph.daddr))
nflags = IFF_BROADCAST;
else if (p.iph.daddr)
nflags = IFF_POINTOPOINT;
if (dev->type != ARPHRD_ETHER) {
unsigned nflags = 0;

if ((dev->flags ^ nflags) &
(IFF_POINTOPOINT | IFF_BROADCAST))
return -EINVAL;
if (ipv4_is_multicast(p.iph.daddr))
nflags = IFF_BROADCAST;
else if (p.iph.daddr)
nflags = IFF_POINTOPOINT;

if ((dev->flags ^ nflags) &
(IFF_POINTOPOINT | IFF_BROADCAST))
return -EINVAL;
}

ipgre_tunnel_unlink(ign, t);
t->parms.iph.saddr = p.iph.saddr;
t->parms.iph.daddr = p.iph.daddr;
t->parms.i_key = p.i_key;
memcpy(dev->dev_addr, &p.iph.saddr, 4);
memcpy(dev->broadcast, &p.iph.daddr, 4);
if (dev->type != ARPHRD_ETHER) {
memcpy(dev->dev_addr, &p.iph.saddr, 4);
memcpy(dev->broadcast, &p.iph.daddr, 4);
}
ipgre_tunnel_link(ign, t);
netdev_state_change(dev);
}
Expand Down

0 comments on commit 2e9526b

Please sign in to comment.