aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/macvlan.c73
-rw-r--r--include/linux/if_link.h3
-rw-r--r--include/linux/if_macvlan.h1
3 files changed, 71 insertions, 6 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index b17fc9007099..9653ed6998fe 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -312,7 +312,8 @@ static int macvlan_open(struct net_device *dev)
312 int err; 312 int err;
313 313
314 if (vlan->port->passthru) { 314 if (vlan->port->passthru) {
315 dev_set_promiscuity(lowerdev, 1); 315 if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
316 dev_set_promiscuity(lowerdev, 1);
316 goto hash_add; 317 goto hash_add;
317 } 318 }
318 319
@@ -344,12 +345,15 @@ static int macvlan_stop(struct net_device *dev)
344 struct macvlan_dev *vlan = netdev_priv(dev); 345 struct macvlan_dev *vlan = netdev_priv(dev);
345 struct net_device *lowerdev = vlan->lowerdev; 346 struct net_device *lowerdev = vlan->lowerdev;
346 347
348 dev_uc_unsync(lowerdev, dev);
349 dev_mc_unsync(lowerdev, dev);
350
347 if (vlan->port->passthru) { 351 if (vlan->port->passthru) {
348 dev_set_promiscuity(lowerdev, -1); 352 if (!(vlan->flags & MACVLAN_FLAG_NOPROMISC))
353 dev_set_promiscuity(lowerdev, -1);
349 goto hash_del; 354 goto hash_del;
350 } 355 }
351 356
352 dev_mc_unsync(lowerdev, dev);
353 if (dev->flags & IFF_ALLMULTI) 357 if (dev->flags & IFF_ALLMULTI)
354 dev_set_allmulti(lowerdev, -1); 358 dev_set_allmulti(lowerdev, -1);
355 359
@@ -399,10 +403,11 @@ static void macvlan_change_rx_flags(struct net_device *dev, int change)
399 dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1); 403 dev_set_allmulti(lowerdev, dev->flags & IFF_ALLMULTI ? 1 : -1);
400} 404}
401 405
402static void macvlan_set_multicast_list(struct net_device *dev) 406static void macvlan_set_mac_lists(struct net_device *dev)
403{ 407{
404 struct macvlan_dev *vlan = netdev_priv(dev); 408 struct macvlan_dev *vlan = netdev_priv(dev);
405 409
410 dev_uc_sync(vlan->lowerdev, dev);
406 dev_mc_sync(vlan->lowerdev, dev); 411 dev_mc_sync(vlan->lowerdev, dev);
407} 412}
408 413
@@ -542,6 +547,43 @@ static int macvlan_vlan_rx_kill_vid(struct net_device *dev,
542 return 0; 547 return 0;
543} 548}
544 549
550static int macvlan_fdb_add(struct ndmsg *ndm,
551 struct net_device *dev,
552 unsigned char *addr,
553 u16 flags)
554{
555 struct macvlan_dev *vlan = netdev_priv(dev);
556 int err = -EINVAL;
557
558 if (!vlan->port->passthru)
559 return -EOPNOTSUPP;
560
561 if (is_unicast_ether_addr(addr))
562 err = dev_uc_add_excl(dev, addr);
563 else if (is_multicast_ether_addr(addr))
564 err = dev_mc_add_excl(dev, addr);
565
566 return err;
567}
568
569static int macvlan_fdb_del(struct ndmsg *ndm,
570 struct net_device *dev,
571 unsigned char *addr)
572{
573 struct macvlan_dev *vlan = netdev_priv(dev);
574 int err = -EINVAL;
575
576 if (!vlan->port->passthru)
577 return -EOPNOTSUPP;
578
579 if (is_unicast_ether_addr(addr))
580 err = dev_uc_del(dev, addr);
581 else if (is_multicast_ether_addr(addr))
582 err = dev_mc_del(dev, addr);
583
584 return err;
585}
586
545static void macvlan_ethtool_get_drvinfo(struct net_device *dev, 587static void macvlan_ethtool_get_drvinfo(struct net_device *dev,
546 struct ethtool_drvinfo *drvinfo) 588 struct ethtool_drvinfo *drvinfo)
547{ 589{
@@ -572,11 +614,14 @@ static const struct net_device_ops macvlan_netdev_ops = {
572 .ndo_change_mtu = macvlan_change_mtu, 614 .ndo_change_mtu = macvlan_change_mtu,
573 .ndo_change_rx_flags = macvlan_change_rx_flags, 615 .ndo_change_rx_flags = macvlan_change_rx_flags,
574 .ndo_set_mac_address = macvlan_set_mac_address, 616 .ndo_set_mac_address = macvlan_set_mac_address,
575 .ndo_set_rx_mode = macvlan_set_multicast_list, 617 .ndo_set_rx_mode = macvlan_set_mac_lists,
576 .ndo_get_stats64 = macvlan_dev_get_stats64, 618 .ndo_get_stats64 = macvlan_dev_get_stats64,
577 .ndo_validate_addr = eth_validate_addr, 619 .ndo_validate_addr = eth_validate_addr,
578 .ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid, 620 .ndo_vlan_rx_add_vid = macvlan_vlan_rx_add_vid,
579 .ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid, 621 .ndo_vlan_rx_kill_vid = macvlan_vlan_rx_kill_vid,
622 .ndo_fdb_add = macvlan_fdb_add,
623 .ndo_fdb_del = macvlan_fdb_del,
624 .ndo_fdb_dump = ndo_dflt_fdb_dump,
580}; 625};
581 626
582void macvlan_common_setup(struct net_device *dev) 627void macvlan_common_setup(struct net_device *dev)
@@ -711,6 +756,9 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,
711 if (data && data[IFLA_MACVLAN_MODE]) 756 if (data && data[IFLA_MACVLAN_MODE])
712 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); 757 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
713 758
759 if (data && data[IFLA_MACVLAN_FLAGS])
760 vlan->flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
761
714 if (vlan->mode == MACVLAN_MODE_PASSTHRU) { 762 if (vlan->mode == MACVLAN_MODE_PASSTHRU) {
715 if (port->count) 763 if (port->count)
716 return -EINVAL; 764 return -EINVAL;
@@ -760,6 +808,16 @@ static int macvlan_changelink(struct net_device *dev,
760 struct macvlan_dev *vlan = netdev_priv(dev); 808 struct macvlan_dev *vlan = netdev_priv(dev);
761 if (data && data[IFLA_MACVLAN_MODE]) 809 if (data && data[IFLA_MACVLAN_MODE])
762 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]); 810 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
811 if (data && data[IFLA_MACVLAN_FLAGS]) {
812 __u16 flags = nla_get_u16(data[IFLA_MACVLAN_FLAGS]);
813 bool promisc = (flags ^ vlan->flags) & MACVLAN_FLAG_NOPROMISC;
814
815 if (promisc && (flags & MACVLAN_FLAG_NOPROMISC))
816 dev_set_promiscuity(vlan->lowerdev, -1);
817 else if (promisc && !(flags & MACVLAN_FLAG_NOPROMISC))
818 dev_set_promiscuity(vlan->lowerdev, 1);
819 vlan->flags = flags;
820 }
763 return 0; 821 return 0;
764} 822}
765 823
@@ -775,6 +833,8 @@ static int macvlan_fill_info(struct sk_buff *skb,
775 833
776 if (nla_put_u32(skb, IFLA_MACVLAN_MODE, vlan->mode)) 834 if (nla_put_u32(skb, IFLA_MACVLAN_MODE, vlan->mode))
777 goto nla_put_failure; 835 goto nla_put_failure;
836 if (nla_put_u16(skb, IFLA_MACVLAN_FLAGS, vlan->flags))
837 goto nla_put_failure;
778 return 0; 838 return 0;
779 839
780nla_put_failure: 840nla_put_failure:
@@ -782,7 +842,8 @@ nla_put_failure:
782} 842}
783 843
784static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = { 844static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
785 [IFLA_MACVLAN_MODE] = { .type = NLA_U32 }, 845 [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
846 [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 },
786}; 847};
787 848
788int macvlan_link_register(struct rtnl_link_ops *ops) 849int macvlan_link_register(struct rtnl_link_ops *ops)
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 2f4fa93454c7..f715750d0b87 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -255,6 +255,7 @@ struct ifla_vlan_qos_mapping {
255enum { 255enum {
256 IFLA_MACVLAN_UNSPEC, 256 IFLA_MACVLAN_UNSPEC,
257 IFLA_MACVLAN_MODE, 257 IFLA_MACVLAN_MODE,
258 IFLA_MACVLAN_FLAGS,
258 __IFLA_MACVLAN_MAX, 259 __IFLA_MACVLAN_MAX,
259}; 260};
260 261
@@ -267,6 +268,8 @@ enum macvlan_mode {
267 MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */ 268 MACVLAN_MODE_PASSTHRU = 8,/* take over the underlying device */
268}; 269};
269 270
271#define MACVLAN_FLAG_NOPROMISC 1
272
270/* SR-IOV virtual function management section */ 273/* SR-IOV virtual function management section */
271 274
272enum { 275enum {
diff --git a/include/linux/if_macvlan.h b/include/linux/if_macvlan.h
index d103dca5c563..f65e8d250f7e 100644
--- a/include/linux/if_macvlan.h
+++ b/include/linux/if_macvlan.h
@@ -60,6 +60,7 @@ struct macvlan_dev {
60 struct net_device *lowerdev; 60 struct net_device *lowerdev;
61 struct macvlan_pcpu_stats __percpu *pcpu_stats; 61 struct macvlan_pcpu_stats __percpu *pcpu_stats;
62 enum macvlan_mode mode; 62 enum macvlan_mode mode;
63 u16 flags;
63 int (*receive)(struct sk_buff *skb); 64 int (*receive)(struct sk_buff *skb);
64 int (*forward)(struct net_device *dev, struct sk_buff *skb); 65 int (*forward)(struct net_device *dev, struct sk_buff *skb);
65 struct macvtap_queue *taps[MAX_MACVTAP_QUEUES]; 66 struct macvtap_queue *taps[MAX_MACVTAP_QUEUES];