aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/macvlan.c56
-rw-r--r--include/linux/if_link.h15
2 files changed, 65 insertions, 6 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d6bd84353f44..322112c7358a 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -33,12 +33,6 @@
33 33
34#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE) 34#define MACVLAN_HASH_SIZE (1 << BITS_PER_BYTE)
35 35
36enum macvlan_mode {
37 MACVLAN_MODE_PRIVATE = 1,
38 MACVLAN_MODE_VEPA = 2,
39 MACVLAN_MODE_BRIDGE = 4,
40};
41
42struct macvlan_port { 36struct macvlan_port {
43 struct net_device *dev; 37 struct net_device *dev;
44 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE]; 38 struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
@@ -614,6 +608,17 @@ static int macvlan_validate(struct nlattr *tb[], struct nlattr *data[])
614 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS]))) 608 if (!is_valid_ether_addr(nla_data(tb[IFLA_ADDRESS])))
615 return -EADDRNOTAVAIL; 609 return -EADDRNOTAVAIL;
616 } 610 }
611
612 if (data && data[IFLA_MACVLAN_MODE]) {
613 switch (nla_get_u32(data[IFLA_MACVLAN_MODE])) {
614 case MACVLAN_MODE_PRIVATE:
615 case MACVLAN_MODE_VEPA:
616 case MACVLAN_MODE_BRIDGE:
617 break;
618 default:
619 return -EINVAL;
620 }
621 }
617 return 0; 622 return 0;
618} 623}
619 624
@@ -678,6 +683,10 @@ static int macvlan_newlink(struct net *src_net, struct net_device *dev,
678 vlan->dev = dev; 683 vlan->dev = dev;
679 vlan->port = port; 684 vlan->port = port;
680 685
686 vlan->mode = MACVLAN_MODE_VEPA;
687 if (data && data[IFLA_MACVLAN_MODE])
688 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
689
681 err = register_netdevice(dev); 690 err = register_netdevice(dev);
682 if (err < 0) 691 if (err < 0)
683 return err; 692 return err;
@@ -699,6 +708,36 @@ static void macvlan_dellink(struct net_device *dev, struct list_head *head)
699 macvlan_port_destroy(port->dev); 708 macvlan_port_destroy(port->dev);
700} 709}
701 710
711static int macvlan_changelink(struct net_device *dev,
712 struct nlattr *tb[], struct nlattr *data[])
713{
714 struct macvlan_dev *vlan = netdev_priv(dev);
715 if (data && data[IFLA_MACVLAN_MODE])
716 vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);
717 return 0;
718}
719
720static size_t macvlan_get_size(const struct net_device *dev)
721{
722 return nla_total_size(4);
723}
724
725static int macvlan_fill_info(struct sk_buff *skb,
726 const struct net_device *dev)
727{
728 struct macvlan_dev *vlan = netdev_priv(dev);
729
730 NLA_PUT_U32(skb, IFLA_MACVLAN_MODE, vlan->mode);
731 return 0;
732
733nla_put_failure:
734 return -EMSGSIZE;
735}
736
737static const struct nla_policy macvlan_policy[IFLA_MACVLAN_MAX + 1] = {
738 [IFLA_MACVLAN_MODE] = { .type = NLA_U32 },
739};
740
702static struct rtnl_link_ops macvlan_link_ops __read_mostly = { 741static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
703 .kind = "macvlan", 742 .kind = "macvlan",
704 .priv_size = sizeof(struct macvlan_dev), 743 .priv_size = sizeof(struct macvlan_dev),
@@ -707,6 +746,11 @@ static struct rtnl_link_ops macvlan_link_ops __read_mostly = {
707 .validate = macvlan_validate, 746 .validate = macvlan_validate,
708 .newlink = macvlan_newlink, 747 .newlink = macvlan_newlink,
709 .dellink = macvlan_dellink, 748 .dellink = macvlan_dellink,
749 .maxtype = IFLA_MACVLAN_MAX,
750 .policy = macvlan_policy,
751 .changelink = macvlan_changelink,
752 .get_size = macvlan_get_size,
753 .fill_info = macvlan_fill_info,
710}; 754};
711 755
712static int macvlan_device_event(struct notifier_block *unused, 756static int macvlan_device_event(struct notifier_block *unused,
diff --git a/include/linux/if_link.h b/include/linux/if_link.h
index 1d3b2425f661..6674791622ca 100644
--- a/include/linux/if_link.h
+++ b/include/linux/if_link.h
@@ -181,4 +181,19 @@ struct ifla_vlan_qos_mapping {
181 __u32 to; 181 __u32 to;
182}; 182};
183 183
184/* MACVLAN section */
185enum {
186 IFLA_MACVLAN_UNSPEC,
187 IFLA_MACVLAN_MODE,
188 __IFLA_MACVLAN_MAX,
189};
190
191#define IFLA_MACVLAN_MAX (__IFLA_MACVLAN_MAX - 1)
192
193enum macvlan_mode {
194 MACVLAN_MODE_PRIVATE = 1, /* don't talk to other macvlans */
195 MACVLAN_MODE_VEPA = 2, /* talk to other ports through ext bridge */
196 MACVLAN_MODE_BRIDGE = 4, /* talk to bridge ports directly */
197};
198
184#endif /* _LINUX_IF_LINK_H */ 199#endif /* _LINUX_IF_LINK_H */