rtnetlink.c (905cf0abe8c2c892313f08e38d808eee4e794987) | rtnetlink.c (2d011be8c07b50e8b3699d06ee11af5f5914b09a) |
---|---|
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> --- 4007 unchanged lines hidden (view full) --- 4016 nlmsg_end(skb, nlh); 4017 return 0; 4018nla_put_failure: 4019 nlmsg_cancel(skb, nlh); 4020 return err ? err : -EMSGSIZE; 4021} 4022EXPORT_SYMBOL_GPL(ndo_dflt_bridge_getlink); 4023 | 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> --- 4007 unchanged lines hidden (view full) --- 4016 nlmsg_end(skb, nlh); 4017 return 0; 4018nla_put_failure: 4019 nlmsg_cancel(skb, nlh); 4020 return err ? err : -EMSGSIZE; 4021} 4022EXPORT_SYMBOL_GPL(ndo_dflt_bridge_getlink); 4023 |
4024static int valid_bridge_getlink_req(const struct nlmsghdr *nlh, 4025 bool strict_check, u32 *filter_mask, 4026 struct netlink_ext_ack *extack) 4027{ 4028 struct nlattr *tb[IFLA_MAX+1]; 4029 int err, i; 4030 4031 if (strict_check) { 4032 struct ifinfomsg *ifm; 4033 4034 if (nlh->nlmsg_len < nlmsg_msg_size(sizeof(*ifm))) { 4035 NL_SET_ERR_MSG(extack, "Invalid header for bridge link dump"); 4036 return -EINVAL; 4037 } 4038 4039 ifm = nlmsg_data(nlh); 4040 if (ifm->__ifi_pad || ifm->ifi_type || ifm->ifi_flags || 4041 ifm->ifi_change || ifm->ifi_index) { 4042 NL_SET_ERR_MSG(extack, "Invalid values in header for bridge link dump request"); 4043 return -EINVAL; 4044 } 4045 4046 err = nlmsg_parse_strict(nlh, sizeof(struct ifinfomsg), tb, 4047 IFLA_MAX, ifla_policy, extack); 4048 } else { 4049 err = nlmsg_parse(nlh, sizeof(struct ifinfomsg), tb, 4050 IFLA_MAX, ifla_policy, extack); 4051 } 4052 if (err < 0) 4053 return err; 4054 4055 /* new attributes should only be added with strict checking */ 4056 for (i = 0; i <= IFLA_MAX; ++i) { 4057 if (!tb[i]) 4058 continue; 4059 4060 switch (i) { 4061 case IFLA_EXT_MASK: 4062 *filter_mask = nla_get_u32(tb[i]); 4063 break; 4064 default: 4065 if (strict_check) { 4066 NL_SET_ERR_MSG(extack, "Unsupported attribute in bridge link dump request"); 4067 return -EINVAL; 4068 } 4069 } 4070 } 4071 4072 return 0; 4073} 4074 |
|
4024static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) 4025{ | 4075static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb) 4076{ |
4077 const struct nlmsghdr *nlh = cb->nlh; |
|
4026 struct net *net = sock_net(skb->sk); 4027 struct net_device *dev; 4028 int idx = 0; 4029 u32 portid = NETLINK_CB(cb->skb).portid; | 4078 struct net *net = sock_net(skb->sk); 4079 struct net_device *dev; 4080 int idx = 0; 4081 u32 portid = NETLINK_CB(cb->skb).portid; |
4030 u32 seq = cb->nlh->nlmsg_seq; | 4082 u32 seq = nlh->nlmsg_seq; |
4031 u32 filter_mask = 0; 4032 int err; 4033 | 4083 u32 filter_mask = 0; 4084 int err; 4085 |
4034 if (nlmsg_len(cb->nlh) > sizeof(struct ifinfomsg)) { 4035 struct nlattr *extfilt; | 4086 err = valid_bridge_getlink_req(nlh, cb->strict_check, &filter_mask, 4087 cb->extack); 4088 if (err < 0 && cb->strict_check) 4089 return err; |
4036 | 4090 |
4037 extfilt = nlmsg_find_attr(cb->nlh, sizeof(struct ifinfomsg), 4038 IFLA_EXT_MASK); 4039 if (extfilt) { 4040 if (nla_len(extfilt) < sizeof(filter_mask)) 4041 return -EINVAL; 4042 4043 filter_mask = nla_get_u32(extfilt); 4044 } 4045 } 4046 | |
4047 rcu_read_lock(); 4048 for_each_netdev_rcu(net, dev) { 4049 const struct net_device_ops *ops = dev->netdev_ops; 4050 struct net_device *br_dev = netdev_master_upper_dev_get(dev); 4051 4052 if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { 4053 if (idx >= cb->args[0]) { 4054 err = br_dev->netdev_ops->ndo_bridge_getlink( --- 865 unchanged lines hidden --- | 4091 rcu_read_lock(); 4092 for_each_netdev_rcu(net, dev) { 4093 const struct net_device_ops *ops = dev->netdev_ops; 4094 struct net_device *br_dev = netdev_master_upper_dev_get(dev); 4095 4096 if (br_dev && br_dev->netdev_ops->ndo_bridge_getlink) { 4097 if (idx >= cb->args[0]) { 4098 err = br_dev->netdev_ops->ndo_bridge_getlink( --- 865 unchanged lines hidden --- |