diff options
Diffstat (limited to 'net/ipv4/ip_gre.c')
-rw-r--r-- | net/ipv4/ip_gre.c | 30 |
1 files changed, 17 insertions, 13 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c index a77807d449e3..a7de9e3a8f18 100644 --- a/net/ipv4/ip_gre.c +++ b/net/ipv4/ip_gre.c | |||
@@ -1476,14 +1476,14 @@ static void ipgre_tap_setup(struct net_device *dev) | |||
1476 | 1476 | ||
1477 | ether_setup(dev); | 1477 | ether_setup(dev); |
1478 | 1478 | ||
1479 | dev->netdev_ops = &ipgre_netdev_ops; | 1479 | dev->netdev_ops = &ipgre_tap_netdev_ops; |
1480 | dev->destructor = free_netdev; | 1480 | dev->destructor = free_netdev; |
1481 | 1481 | ||
1482 | dev->iflink = 0; | 1482 | dev->iflink = 0; |
1483 | dev->features |= NETIF_F_NETNS_LOCAL; | 1483 | dev->features |= NETIF_F_NETNS_LOCAL; |
1484 | } | 1484 | } |
1485 | 1485 | ||
1486 | static int ipgre_newlink(struct net_device *dev, struct nlattr *tb[], | 1486 | static int ipgre_newlink(struct net *src_net, struct net_device *dev, struct nlattr *tb[], |
1487 | struct nlattr *data[]) | 1487 | struct nlattr *data[]) |
1488 | { | 1488 | { |
1489 | struct ip_tunnel *nt; | 1489 | struct ip_tunnel *nt; |
@@ -1537,25 +1537,29 @@ static int ipgre_changelink(struct net_device *dev, struct nlattr *tb[], | |||
1537 | if (t->dev != dev) | 1537 | if (t->dev != dev) |
1538 | return -EEXIST; | 1538 | return -EEXIST; |
1539 | } else { | 1539 | } else { |
1540 | unsigned nflags = 0; | ||
1541 | |||
1542 | t = nt; | 1540 | t = nt; |
1543 | 1541 | ||
1544 | if (ipv4_is_multicast(p.iph.daddr)) | 1542 | if (dev->type != ARPHRD_ETHER) { |
1545 | nflags = IFF_BROADCAST; | 1543 | unsigned nflags = 0; |
1546 | else if (p.iph.daddr) | ||
1547 | nflags = IFF_POINTOPOINT; | ||
1548 | 1544 | ||
1549 | if ((dev->flags ^ nflags) & | 1545 | if (ipv4_is_multicast(p.iph.daddr)) |
1550 | (IFF_POINTOPOINT | IFF_BROADCAST)) | 1546 | nflags = IFF_BROADCAST; |
1551 | return -EINVAL; | 1547 | else if (p.iph.daddr) |
1548 | nflags = IFF_POINTOPOINT; | ||
1549 | |||
1550 | if ((dev->flags ^ nflags) & | ||
1551 | (IFF_POINTOPOINT | IFF_BROADCAST)) | ||
1552 | return -EINVAL; | ||
1553 | } | ||
1552 | 1554 | ||
1553 | ipgre_tunnel_unlink(ign, t); | 1555 | ipgre_tunnel_unlink(ign, t); |
1554 | t->parms.iph.saddr = p.iph.saddr; | 1556 | t->parms.iph.saddr = p.iph.saddr; |
1555 | t->parms.iph.daddr = p.iph.daddr; | 1557 | t->parms.iph.daddr = p.iph.daddr; |
1556 | t->parms.i_key = p.i_key; | 1558 | t->parms.i_key = p.i_key; |
1557 | memcpy(dev->dev_addr, &p.iph.saddr, 4); | 1559 | if (dev->type != ARPHRD_ETHER) { |
1558 | memcpy(dev->broadcast, &p.iph.daddr, 4); | 1560 | memcpy(dev->dev_addr, &p.iph.saddr, 4); |
1561 | memcpy(dev->broadcast, &p.iph.daddr, 4); | ||
1562 | } | ||
1559 | ipgre_tunnel_link(ign, t); | 1563 | ipgre_tunnel_link(ign, t); |
1560 | netdev_state_change(dev); | 1564 | netdev_state_change(dev); |
1561 | } | 1565 | } |