aboutsummaryrefslogtreecommitdiffstats
path: root/net/core/rtnetlink.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/core/rtnetlink.c')
-rw-r--r--net/core/rtnetlink.c238
1 files changed, 226 insertions, 12 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 31e85d327aa..e4b9870e470 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -98,7 +98,7 @@ int lockdep_rtnl_is_held(void)
98EXPORT_SYMBOL(lockdep_rtnl_is_held); 98EXPORT_SYMBOL(lockdep_rtnl_is_held);
99#endif /* #ifdef CONFIG_PROVE_LOCKING */ 99#endif /* #ifdef CONFIG_PROVE_LOCKING */
100 100
101static struct rtnl_link *rtnl_msg_handlers[NPROTO]; 101static struct rtnl_link *rtnl_msg_handlers[RTNL_FAMILY_MAX + 1];
102 102
103static inline int rtm_msgindex(int msgtype) 103static inline int rtm_msgindex(int msgtype)
104{ 104{
@@ -118,7 +118,11 @@ static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex)
118{ 118{
119 struct rtnl_link *tab; 119 struct rtnl_link *tab;
120 120
121 tab = rtnl_msg_handlers[protocol]; 121 if (protocol <= RTNL_FAMILY_MAX)
122 tab = rtnl_msg_handlers[protocol];
123 else
124 tab = NULL;
125
122 if (tab == NULL || tab[msgindex].doit == NULL) 126 if (tab == NULL || tab[msgindex].doit == NULL)
123 tab = rtnl_msg_handlers[PF_UNSPEC]; 127 tab = rtnl_msg_handlers[PF_UNSPEC];
124 128
@@ -129,7 +133,11 @@ static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
129{ 133{
130 struct rtnl_link *tab; 134 struct rtnl_link *tab;
131 135
132 tab = rtnl_msg_handlers[protocol]; 136 if (protocol <= RTNL_FAMILY_MAX)
137 tab = rtnl_msg_handlers[protocol];
138 else
139 tab = NULL;
140
133 if (tab == NULL || tab[msgindex].dumpit == NULL) 141 if (tab == NULL || tab[msgindex].dumpit == NULL)
134 tab = rtnl_msg_handlers[PF_UNSPEC]; 142 tab = rtnl_msg_handlers[PF_UNSPEC];
135 143
@@ -159,7 +167,7 @@ int __rtnl_register(int protocol, int msgtype,
159 struct rtnl_link *tab; 167 struct rtnl_link *tab;
160 int msgindex; 168 int msgindex;
161 169
162 BUG_ON(protocol < 0 || protocol >= NPROTO); 170 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
163 msgindex = rtm_msgindex(msgtype); 171 msgindex = rtm_msgindex(msgtype);
164 172
165 tab = rtnl_msg_handlers[protocol]; 173 tab = rtnl_msg_handlers[protocol];
@@ -211,7 +219,7 @@ int rtnl_unregister(int protocol, int msgtype)
211{ 219{
212 int msgindex; 220 int msgindex;
213 221
214 BUG_ON(protocol < 0 || protocol >= NPROTO); 222 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
215 msgindex = rtm_msgindex(msgtype); 223 msgindex = rtm_msgindex(msgtype);
216 224
217 if (rtnl_msg_handlers[protocol] == NULL) 225 if (rtnl_msg_handlers[protocol] == NULL)
@@ -233,7 +241,7 @@ EXPORT_SYMBOL_GPL(rtnl_unregister);
233 */ 241 */
234void rtnl_unregister_all(int protocol) 242void rtnl_unregister_all(int protocol)
235{ 243{
236 BUG_ON(protocol < 0 || protocol >= NPROTO); 244 BUG_ON(protocol < 0 || protocol > RTNL_FAMILY_MAX);
237 245
238 kfree(rtnl_msg_handlers[protocol]); 246 kfree(rtnl_msg_handlers[protocol]);
239 rtnl_msg_handlers[protocol] = NULL; 247 rtnl_msg_handlers[protocol] = NULL;
@@ -600,7 +608,41 @@ static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
600 608
601 a->rx_compressed = b->rx_compressed; 609 a->rx_compressed = b->rx_compressed;
602 a->tx_compressed = b->tx_compressed; 610 a->tx_compressed = b->tx_compressed;
603}; 611}
612
613static void copy_rtnl_link_stats64(void *v, const struct net_device_stats *b)
614{
615 struct rtnl_link_stats64 a;
616
617 a.rx_packets = b->rx_packets;
618 a.tx_packets = b->tx_packets;
619 a.rx_bytes = b->rx_bytes;
620 a.tx_bytes = b->tx_bytes;
621 a.rx_errors = b->rx_errors;
622 a.tx_errors = b->tx_errors;
623 a.rx_dropped = b->rx_dropped;
624 a.tx_dropped = b->tx_dropped;
625
626 a.multicast = b->multicast;
627 a.collisions = b->collisions;
628
629 a.rx_length_errors = b->rx_length_errors;
630 a.rx_over_errors = b->rx_over_errors;
631 a.rx_crc_errors = b->rx_crc_errors;
632 a.rx_frame_errors = b->rx_frame_errors;
633 a.rx_fifo_errors = b->rx_fifo_errors;
634 a.rx_missed_errors = b->rx_missed_errors;
635
636 a.tx_aborted_errors = b->tx_aborted_errors;
637 a.tx_carrier_errors = b->tx_carrier_errors;
638 a.tx_fifo_errors = b->tx_fifo_errors;
639 a.tx_heartbeat_errors = b->tx_heartbeat_errors;
640 a.tx_window_errors = b->tx_window_errors;
641
642 a.rx_compressed = b->rx_compressed;
643 a.tx_compressed = b->tx_compressed;
644 memcpy(v, &a, sizeof(a));
645}
604 646
605/* All VF info */ 647/* All VF info */
606static inline int rtnl_vfinfo_size(const struct net_device *dev) 648static inline int rtnl_vfinfo_size(const struct net_device *dev)
@@ -618,6 +660,31 @@ static inline int rtnl_vfinfo_size(const struct net_device *dev)
618 return 0; 660 return 0;
619} 661}
620 662
663static size_t rtnl_port_size(const struct net_device *dev)
664{
665 size_t port_size = nla_total_size(4) /* PORT_VF */
666 + nla_total_size(PORT_PROFILE_MAX) /* PORT_PROFILE */
667 + nla_total_size(sizeof(struct ifla_port_vsi))
668 /* PORT_VSI_TYPE */
669 + nla_total_size(PORT_UUID_MAX) /* PORT_INSTANCE_UUID */
670 + nla_total_size(PORT_UUID_MAX) /* PORT_HOST_UUID */
671 + nla_total_size(1) /* PROT_VDP_REQUEST */
672 + nla_total_size(2); /* PORT_VDP_RESPONSE */
673 size_t vf_ports_size = nla_total_size(sizeof(struct nlattr));
674 size_t vf_port_size = nla_total_size(sizeof(struct nlattr))
675 + port_size;
676 size_t port_self_size = nla_total_size(sizeof(struct nlattr))
677 + port_size;
678
679 if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent)
680 return 0;
681 if (dev_num_vf(dev->dev.parent))
682 return port_self_size + vf_ports_size +
683 vf_port_size * dev_num_vf(dev->dev.parent);
684 else
685 return port_self_size;
686}
687
621static inline size_t if_nlmsg_size(const struct net_device *dev) 688static inline size_t if_nlmsg_size(const struct net_device *dev)
622{ 689{
623 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 690 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
@@ -626,6 +693,7 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
626 + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */ 693 + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */
627 + nla_total_size(sizeof(struct rtnl_link_ifmap)) 694 + nla_total_size(sizeof(struct rtnl_link_ifmap))
628 + nla_total_size(sizeof(struct rtnl_link_stats)) 695 + nla_total_size(sizeof(struct rtnl_link_stats))
696 + nla_total_size(sizeof(struct rtnl_link_stats64))
629 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ 697 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
630 + nla_total_size(MAX_ADDR_LEN) /* IFLA_BROADCAST */ 698 + nla_total_size(MAX_ADDR_LEN) /* IFLA_BROADCAST */
631 + nla_total_size(4) /* IFLA_TXQLEN */ 699 + nla_total_size(4) /* IFLA_TXQLEN */
@@ -637,9 +705,82 @@ static inline size_t if_nlmsg_size(const struct net_device *dev)
637 + nla_total_size(1) /* IFLA_LINKMODE */ 705 + nla_total_size(1) /* IFLA_LINKMODE */
638 + nla_total_size(4) /* IFLA_NUM_VF */ 706 + nla_total_size(4) /* IFLA_NUM_VF */
639 + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */ 707 + rtnl_vfinfo_size(dev) /* IFLA_VFINFO_LIST */
708 + rtnl_port_size(dev) /* IFLA_VF_PORTS + IFLA_PORT_SELF */
640 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */ 709 + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
641} 710}
642 711
712static int rtnl_vf_ports_fill(struct sk_buff *skb, struct net_device *dev)
713{
714 struct nlattr *vf_ports;
715 struct nlattr *vf_port;
716 int vf;
717 int err;
718
719 vf_ports = nla_nest_start(skb, IFLA_VF_PORTS);
720 if (!vf_ports)
721 return -EMSGSIZE;
722
723 for (vf = 0; vf < dev_num_vf(dev->dev.parent); vf++) {
724 vf_port = nla_nest_start(skb, IFLA_VF_PORT);
725 if (!vf_port) {
726 nla_nest_cancel(skb, vf_ports);
727 return -EMSGSIZE;
728 }
729 NLA_PUT_U32(skb, IFLA_PORT_VF, vf);
730 err = dev->netdev_ops->ndo_get_vf_port(dev, vf, skb);
731 if (err) {
732nla_put_failure:
733 nla_nest_cancel(skb, vf_port);
734 continue;
735 }
736 nla_nest_end(skb, vf_port);
737 }
738
739 nla_nest_end(skb, vf_ports);
740
741 return 0;
742}
743
744static int rtnl_port_self_fill(struct sk_buff *skb, struct net_device *dev)
745{
746 struct nlattr *port_self;
747 int err;
748
749 port_self = nla_nest_start(skb, IFLA_PORT_SELF);
750 if (!port_self)
751 return -EMSGSIZE;
752
753 err = dev->netdev_ops->ndo_get_vf_port(dev, PORT_SELF_VF, skb);
754 if (err) {
755 nla_nest_cancel(skb, port_self);
756 return err;
757 }
758
759 nla_nest_end(skb, port_self);
760
761 return 0;
762}
763
764static int rtnl_port_fill(struct sk_buff *skb, struct net_device *dev)
765{
766 int err;
767
768 if (!dev->netdev_ops->ndo_get_vf_port || !dev->dev.parent)
769 return 0;
770
771 err = rtnl_port_self_fill(skb, dev);
772 if (err)
773 return err;
774
775 if (dev_num_vf(dev->dev.parent)) {
776 err = rtnl_vf_ports_fill(skb, dev);
777 if (err)
778 return err;
779 }
780
781 return 0;
782}
783
643static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev, 784static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
644 int type, u32 pid, u32 seq, u32 change, 785 int type, u32 pid, u32 seq, u32 change,
645 unsigned int flags) 786 unsigned int flags)
@@ -705,13 +846,21 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
705 stats = dev_get_stats(dev); 846 stats = dev_get_stats(dev);
706 copy_rtnl_link_stats(nla_data(attr), stats); 847 copy_rtnl_link_stats(nla_data(attr), stats);
707 848
849 attr = nla_reserve(skb, IFLA_STATS64,
850 sizeof(struct rtnl_link_stats64));
851 if (attr == NULL)
852 goto nla_put_failure;
853 copy_rtnl_link_stats64(nla_data(attr), stats);
854
855 if (dev->dev.parent)
856 NLA_PUT_U32(skb, IFLA_NUM_VF, dev_num_vf(dev->dev.parent));
857
708 if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) { 858 if (dev->netdev_ops->ndo_get_vf_config && dev->dev.parent) {
709 int i; 859 int i;
710 860
711 struct nlattr *vfinfo, *vf; 861 struct nlattr *vfinfo, *vf;
712 int num_vfs = dev_num_vf(dev->dev.parent); 862 int num_vfs = dev_num_vf(dev->dev.parent);
713 863
714 NLA_PUT_U32(skb, IFLA_NUM_VF, num_vfs);
715 vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST); 864 vfinfo = nla_nest_start(skb, IFLA_VFINFO_LIST);
716 if (!vfinfo) 865 if (!vfinfo)
717 goto nla_put_failure; 866 goto nla_put_failure;
@@ -739,6 +888,10 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
739 } 888 }
740 nla_nest_end(skb, vfinfo); 889 nla_nest_end(skb, vfinfo);
741 } 890 }
891
892 if (rtnl_port_fill(skb, dev))
893 goto nla_put_failure;
894
742 if (dev->rtnl_link_ops) { 895 if (dev->rtnl_link_ops) {
743 if (rtnl_link_fill(skb, dev) < 0) 896 if (rtnl_link_fill(skb, dev) < 0)
744 goto nla_put_failure; 897 goto nla_put_failure;
@@ -800,6 +953,8 @@ const struct nla_policy ifla_policy[IFLA_MAX+1] = {
800 [IFLA_NET_NS_PID] = { .type = NLA_U32 }, 953 [IFLA_NET_NS_PID] = { .type = NLA_U32 },
801 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 }, 954 [IFLA_IFALIAS] = { .type = NLA_STRING, .len = IFALIASZ-1 },
802 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED }, 955 [IFLA_VFINFO_LIST] = {. type = NLA_NESTED },
956 [IFLA_VF_PORTS] = { .type = NLA_NESTED },
957 [IFLA_PORT_SELF] = { .type = NLA_NESTED },
803}; 958};
804EXPORT_SYMBOL(ifla_policy); 959EXPORT_SYMBOL(ifla_policy);
805 960
@@ -821,6 +976,20 @@ static const struct nla_policy ifla_vf_policy[IFLA_VF_MAX+1] = {
821 .len = sizeof(struct ifla_vf_tx_rate) }, 976 .len = sizeof(struct ifla_vf_tx_rate) },
822}; 977};
823 978
979static const struct nla_policy ifla_port_policy[IFLA_PORT_MAX+1] = {
980 [IFLA_PORT_VF] = { .type = NLA_U32 },
981 [IFLA_PORT_PROFILE] = { .type = NLA_STRING,
982 .len = PORT_PROFILE_MAX },
983 [IFLA_PORT_VSI_TYPE] = { .type = NLA_BINARY,
984 .len = sizeof(struct ifla_port_vsi)},
985 [IFLA_PORT_INSTANCE_UUID] = { .type = NLA_BINARY,
986 .len = PORT_UUID_MAX },
987 [IFLA_PORT_HOST_UUID] = { .type = NLA_STRING,
988 .len = PORT_UUID_MAX },
989 [IFLA_PORT_REQUEST] = { .type = NLA_U8, },
990 [IFLA_PORT_RESPONSE] = { .type = NLA_U16, },
991};
992
824struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) 993struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[])
825{ 994{
826 struct net *net; 995 struct net *net;
@@ -1040,6 +1209,53 @@ static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
1040 } 1209 }
1041 err = 0; 1210 err = 0;
1042 1211
1212 if (tb[IFLA_VF_PORTS]) {
1213 struct nlattr *port[IFLA_PORT_MAX+1];
1214 struct nlattr *attr;
1215 int vf;
1216 int rem;
1217
1218 err = -EOPNOTSUPP;
1219 if (!ops->ndo_set_vf_port)
1220 goto errout;
1221
1222 nla_for_each_nested(attr, tb[IFLA_VF_PORTS], rem) {
1223 if (nla_type(attr) != IFLA_VF_PORT)
1224 continue;
1225 err = nla_parse_nested(port, IFLA_PORT_MAX,
1226 attr, ifla_port_policy);
1227 if (err < 0)
1228 goto errout;
1229 if (!port[IFLA_PORT_VF]) {
1230 err = -EOPNOTSUPP;
1231 goto errout;
1232 }
1233 vf = nla_get_u32(port[IFLA_PORT_VF]);
1234 err = ops->ndo_set_vf_port(dev, vf, port);
1235 if (err < 0)
1236 goto errout;
1237 modified = 1;
1238 }
1239 }
1240 err = 0;
1241
1242 if (tb[IFLA_PORT_SELF]) {
1243 struct nlattr *port[IFLA_PORT_MAX+1];
1244
1245 err = nla_parse_nested(port, IFLA_PORT_MAX,
1246 tb[IFLA_PORT_SELF], ifla_port_policy);
1247 if (err < 0)
1248 goto errout;
1249
1250 err = -EOPNOTSUPP;
1251 if (ops->ndo_set_vf_port)
1252 err = ops->ndo_set_vf_port(dev, PORT_SELF_VF, port);
1253 if (err < 0)
1254 goto errout;
1255 modified = 1;
1256 }
1257 err = 0;
1258
1043errout: 1259errout:
1044 if (err < 0 && modified && net_ratelimit()) 1260 if (err < 0 && modified && net_ratelimit())
1045 printk(KERN_WARNING "A link change request failed with " 1261 printk(KERN_WARNING "A link change request failed with "
@@ -1397,7 +1613,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
1397 1613
1398 if (s_idx == 0) 1614 if (s_idx == 0)
1399 s_idx = 1; 1615 s_idx = 1;
1400 for (idx = 1; idx < NPROTO; idx++) { 1616 for (idx = 1; idx <= RTNL_FAMILY_MAX; idx++) {
1401 int type = cb->nlh->nlmsg_type-RTM_BASE; 1617 int type = cb->nlh->nlmsg_type-RTM_BASE;
1402 if (idx < s_idx || idx == PF_PACKET) 1618 if (idx < s_idx || idx == PF_PACKET)
1403 continue; 1619 continue;
@@ -1465,9 +1681,6 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1465 return 0; 1681 return 0;
1466 1682
1467 family = ((struct rtgenmsg *)NLMSG_DATA(nlh))->rtgen_family; 1683 family = ((struct rtgenmsg *)NLMSG_DATA(nlh))->rtgen_family;
1468 if (family >= NPROTO)
1469 return -EAFNOSUPPORT;
1470
1471 sz_idx = type>>2; 1684 sz_idx = type>>2;
1472 kind = type&3; 1685 kind = type&3;
1473 1686
@@ -1535,6 +1748,7 @@ static int rtnetlink_event(struct notifier_block *this, unsigned long event, voi
1535 case NETDEV_POST_INIT: 1748 case NETDEV_POST_INIT:
1536 case NETDEV_REGISTER: 1749 case NETDEV_REGISTER:
1537 case NETDEV_CHANGE: 1750 case NETDEV_CHANGE:
1751 case NETDEV_PRE_TYPE_CHANGE:
1538 case NETDEV_GOING_DOWN: 1752 case NETDEV_GOING_DOWN:
1539 case NETDEV_UNREGISTER: 1753 case NETDEV_UNREGISTER:
1540 case NETDEV_UNREGISTER_BATCH: 1754 case NETDEV_UNREGISTER_BATCH: