rtnetlink.c (e0d087af725b09358336098a6b57bb7f90f96175) | rtnetlink.c (81adee47dfb608df3ad0b91d230fb3cef75f0060) |
---|---|
1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 719 unchanged lines hidden (view full) --- 728}; 729EXPORT_SYMBOL(ifla_policy); 730 731static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 732 [IFLA_INFO_KIND] = { .type = NLA_STRING }, 733 [IFLA_INFO_DATA] = { .type = NLA_NESTED }, 734}; 735 | 1/* 2 * INET An implementation of the TCP/IP protocol suite for the LINUX 3 * operating system. INET is implemented using the BSD Socket 4 * interface as the means of communication with the user level. 5 * 6 * Routing netlink socket interface: protocol independent part. 7 * 8 * Authors: Alexey Kuznetsov, <kuznet@ms2.inr.ac.ru> --- 719 unchanged lines hidden (view full) --- 728}; 729EXPORT_SYMBOL(ifla_policy); 730 731static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = { 732 [IFLA_INFO_KIND] = { .type = NLA_STRING }, 733 [IFLA_INFO_DATA] = { .type = NLA_NESTED }, 734}; 735 |
736struct net *rtnl_link_get_net(struct net *src_net, struct nlattr *tb[]) 737{ 738 struct net *net; 739 /* Examine the link attributes and figure out which 740 * network namespace we are talking about. 741 */ 742 if (tb[IFLA_NET_NS_PID]) 743 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); 744 else 745 net = get_net(src_net); 746 return net; 747} 748EXPORT_SYMBOL(rtnl_link_get_net); 749 |
|
736static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) 737{ 738 if (dev) { 739 if (tb[IFLA_ADDRESS] && 740 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) 741 return -EINVAL; 742 743 if (tb[IFLA_BROADCAST] && --- 7 unchanged lines hidden (view full) --- 751static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, 752 struct nlattr **tb, char *ifname, int modified) 753{ 754 const struct net_device_ops *ops = dev->netdev_ops; 755 int send_addr_notify = 0; 756 int err; 757 758 if (tb[IFLA_NET_NS_PID]) { | 750static int validate_linkmsg(struct net_device *dev, struct nlattr *tb[]) 751{ 752 if (dev) { 753 if (tb[IFLA_ADDRESS] && 754 nla_len(tb[IFLA_ADDRESS]) < dev->addr_len) 755 return -EINVAL; 756 757 if (tb[IFLA_BROADCAST] && --- 7 unchanged lines hidden (view full) --- 765static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm, 766 struct nlattr **tb, char *ifname, int modified) 767{ 768 const struct net_device_ops *ops = dev->netdev_ops; 769 int send_addr_notify = 0; 770 int err; 771 772 if (tb[IFLA_NET_NS_PID]) { |
759 struct net *net; 760 net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID])); | 773 struct net *net = rtnl_link_get_net(dev_net(dev), tb); |
761 if (IS_ERR(net)) { 762 err = PTR_ERR(net); 763 goto errout; 764 } 765 err = dev_change_net_namespace(dev, net, ifname); 766 put_net(net); 767 if (err) 768 goto errout; --- 202 unchanged lines hidden (view full) --- 971 ops = dev->rtnl_link_ops; 972 if (!ops) 973 return -EOPNOTSUPP; 974 975 ops->dellink(dev, NULL); 976 return 0; 977} 978 | 774 if (IS_ERR(net)) { 775 err = PTR_ERR(net); 776 goto errout; 777 } 778 err = dev_change_net_namespace(dev, net, ifname); 779 put_net(net); 780 if (err) 781 goto errout; --- 202 unchanged lines hidden (view full) --- 984 ops = dev->rtnl_link_ops; 985 if (!ops) 986 return -EOPNOTSUPP; 987 988 ops->dellink(dev, NULL); 989 return 0; 990} 991 |
979struct net_device *rtnl_create_link(struct net *net, char *ifname, 980 const struct rtnl_link_ops *ops, struct nlattr *tb[]) | 992struct net_device *rtnl_create_link(struct net *src_net, struct net *net, 993 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[]) |
981{ 982 int err; 983 struct net_device *dev; 984 unsigned int num_queues = 1; 985 unsigned int real_num_queues = 1; 986 987 if (ops->get_tx_queues) { | 994{ 995 int err; 996 struct net_device *dev; 997 unsigned int num_queues = 1; 998 unsigned int real_num_queues = 1; 999 1000 if (ops->get_tx_queues) { |
988 err = ops->get_tx_queues(net, tb, &num_queues, | 1001 err = ops->get_tx_queues(src_net, tb, &num_queues, |
989 &real_num_queues); 990 if (err) 991 goto err; 992 } 993 err = -ENOMEM; 994 dev = alloc_netdev_mq(ops->priv_size, ifname, ops->setup, num_queues); 995 if (!dev) 996 goto err; 997 | 1002 &real_num_queues); 1003 if (err) 1004 goto err; 1005 } 1006 err = -ENOMEM; 1007 dev = alloc_netdev_mq(ops->priv_size, ifname, ops->setup, num_queues); 1008 if (!dev) 1009 goto err; 1010 |
1011 dev_net_set(dev, net); 1012 dev->rtnl_link_ops = ops; |
|
998 dev->real_num_tx_queues = real_num_queues; | 1013 dev->real_num_tx_queues = real_num_queues; |
1014 |
|
999 if (strchr(dev->name, '%')) { 1000 err = dev_alloc_name(dev, dev->name); 1001 if (err < 0) 1002 goto err_free; 1003 } 1004 | 1015 if (strchr(dev->name, '%')) { 1016 err = dev_alloc_name(dev, dev->name); 1017 if (err < 0) 1018 goto err_free; 1019 } 1020 |
1005 dev_net_set(dev, net); 1006 dev->rtnl_link_ops = ops; 1007 | |
1008 if (tb[IFLA_MTU]) 1009 dev->mtu = nla_get_u32(tb[IFLA_MTU]); 1010 if (tb[IFLA_ADDRESS]) 1011 memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]), 1012 nla_len(tb[IFLA_ADDRESS])); 1013 if (tb[IFLA_BROADCAST]) 1014 memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]), 1015 nla_len(tb[IFLA_BROADCAST])); --- 62 unchanged lines hidden (view full) --- 1078 ops = rtnl_link_ops_get(kind); 1079 } else { 1080 kind[0] = '\0'; 1081 ops = NULL; 1082 } 1083 1084 if (1) { 1085 struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL; | 1021 if (tb[IFLA_MTU]) 1022 dev->mtu = nla_get_u32(tb[IFLA_MTU]); 1023 if (tb[IFLA_ADDRESS]) 1024 memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]), 1025 nla_len(tb[IFLA_ADDRESS])); 1026 if (tb[IFLA_BROADCAST]) 1027 memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]), 1028 nla_len(tb[IFLA_BROADCAST])); --- 62 unchanged lines hidden (view full) --- 1091 ops = rtnl_link_ops_get(kind); 1092 } else { 1093 kind[0] = '\0'; 1094 ops = NULL; 1095 } 1096 1097 if (1) { 1098 struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL; |
1099 struct net *dest_net; |
|
1086 1087 if (ops) { 1088 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) { 1089 err = nla_parse_nested(attr, ops->maxtype, 1090 linkinfo[IFLA_INFO_DATA], 1091 ops->policy); 1092 if (err < 0) 1093 return err; --- 48 unchanged lines hidden (view full) --- 1142 } 1143#endif 1144 return -EOPNOTSUPP; 1145 } 1146 1147 if (!ifname[0]) 1148 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); 1149 | 1100 1101 if (ops) { 1102 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) { 1103 err = nla_parse_nested(attr, ops->maxtype, 1104 linkinfo[IFLA_INFO_DATA], 1105 ops->policy); 1106 if (err < 0) 1107 return err; --- 48 unchanged lines hidden (view full) --- 1156 } 1157#endif 1158 return -EOPNOTSUPP; 1159 } 1160 1161 if (!ifname[0]) 1162 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); 1163 |
1150 dev = rtnl_create_link(net, ifname, ops, tb); | 1164 dest_net = rtnl_link_get_net(net, tb); 1165 dev = rtnl_create_link(net, dest_net, ifname, ops, tb); |
1151 1152 if (IS_ERR(dev)) 1153 err = PTR_ERR(dev); 1154 else if (ops->newlink) | 1166 1167 if (IS_ERR(dev)) 1168 err = PTR_ERR(dev); 1169 else if (ops->newlink) |
1155 err = ops->newlink(dev, tb, data); | 1170 err = ops->newlink(net, dev, tb, data); |
1156 else 1157 err = register_netdevice(dev); | 1171 else 1172 err = register_netdevice(dev); |
1158 | |
1159 if (err < 0 && !IS_ERR(dev)) 1160 free_netdev(dev); | 1173 if (err < 0 && !IS_ERR(dev)) 1174 free_netdev(dev); |
1175 1176 put_net(dest_net); |
|
1161 return err; 1162 } 1163} 1164 1165static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1166{ 1167 struct net *net = sock_net(skb->sk); 1168 struct ifinfomsg *ifm; --- 253 unchanged lines hidden --- | 1177 return err; 1178 } 1179} 1180 1181static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg) 1182{ 1183 struct net *net = sock_net(skb->sk); 1184 struct ifinfomsg *ifm; --- 253 unchanged lines hidden --- |