gre: Fix dev_addr clobbering for gretap

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 <herbert@gondor.apana.org.au>
Acked-by: Stephen Hemminger <shemminger@vyatta.com>
Tested-by: Nathan Neulinger <nneul@mst.edu>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by Herbert Xu and committed by David S. Miller 2e9526b3 33cb7d33

+16 -12
+16 -12
net/ipv4/ip_gre.c
··· 1464 1465 ether_setup(dev); 1466 1467 - dev->netdev_ops = &ipgre_netdev_ops; 1468 dev->destructor = free_netdev; 1469 1470 dev->iflink = 0; ··· 1525 if (t->dev != dev) 1526 return -EEXIST; 1527 } else { 1528 - unsigned nflags = 0; 1529 - 1530 t = nt; 1531 1532 - if (ipv4_is_multicast(p.iph.daddr)) 1533 - nflags = IFF_BROADCAST; 1534 - else if (p.iph.daddr) 1535 - nflags = IFF_POINTOPOINT; 1536 1537 - if ((dev->flags ^ nflags) & 1538 - (IFF_POINTOPOINT | IFF_BROADCAST)) 1539 - return -EINVAL; 1540 1541 ipgre_tunnel_unlink(ign, t); 1542 t->parms.iph.saddr = p.iph.saddr; 1543 t->parms.iph.daddr = p.iph.daddr; 1544 t->parms.i_key = p.i_key; 1545 - memcpy(dev->dev_addr, &p.iph.saddr, 4); 1546 - memcpy(dev->broadcast, &p.iph.daddr, 4); 1547 ipgre_tunnel_link(ign, t); 1548 netdev_state_change(dev); 1549 }
··· 1464 1465 ether_setup(dev); 1466 1467 + dev->netdev_ops = &ipgre_tap_netdev_ops; 1468 dev->destructor = free_netdev; 1469 1470 dev->iflink = 0; ··· 1525 if (t->dev != dev) 1526 return -EEXIST; 1527 } else { 1528 t = nt; 1529 1530 + if (dev->type != ARPHRD_ETHER) { 1531 + unsigned nflags = 0; 1532 1533 + if (ipv4_is_multicast(p.iph.daddr)) 1534 + nflags = IFF_BROADCAST; 1535 + else if (p.iph.daddr) 1536 + nflags = IFF_POINTOPOINT; 1537 + 1538 + if ((dev->flags ^ nflags) & 1539 + (IFF_POINTOPOINT | IFF_BROADCAST)) 1540 + return -EINVAL; 1541 + } 1542 1543 ipgre_tunnel_unlink(ign, t); 1544 t->parms.iph.saddr = p.iph.saddr; 1545 t->parms.iph.daddr = p.iph.daddr; 1546 t->parms.i_key = p.i_key; 1547 + if (dev->type != ARPHRD_ETHER) { 1548 + memcpy(dev->dev_addr, &p.iph.saddr, 4); 1549 + memcpy(dev->broadcast, &p.iph.daddr, 4); 1550 + } 1551 ipgre_tunnel_link(ign, t); 1552 netdev_state_change(dev); 1553 }