rtnetlink.c (d70522fc541224b8351ac26f4765f2c6268f8d72) | rtnetlink.c (14d7b8122fd591693a2388b98563707ba72c6780) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * INET An implementation of the TCP/IP protocol suite for the LINUX 4 * operating system. INET is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * Routing netlink socket interface: protocol independent part. 8 * --- 40 unchanged lines hidden (view full) --- 49#include <net/udp.h> 50#include <net/tcp.h> 51#include <net/sock.h> 52#include <net/pkt_sched.h> 53#include <net/fib_rules.h> 54#include <net/rtnetlink.h> 55#include <net/net_namespace.h> 56 | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * INET An implementation of the TCP/IP protocol suite for the LINUX 4 * operating system. INET is implemented using the BSD Socket 5 * interface as the means of communication with the user level. 6 * 7 * Routing netlink socket interface: protocol independent part. 8 * --- 40 unchanged lines hidden (view full) --- 49#include <net/udp.h> 50#include <net/tcp.h> 51#include <net/sock.h> 52#include <net/pkt_sched.h> 53#include <net/fib_rules.h> 54#include <net/rtnetlink.h> 55#include <net/net_namespace.h> 56 |
57#include "dev.h" 58 |
|
57#define RTNL_MAX_TYPE 50 58#define RTNL_SLAVE_MAX_TYPE 40 59 60struct rtnl_link { 61 rtnl_doit_func doit; 62 rtnl_dumpit_func dumpit; 63 struct module *owner; 64 unsigned int flags; --- 25 unchanged lines hidden (view full) --- 90EXPORT_SYMBOL(rtnl_kfree_skbs); 91 92void __rtnl_unlock(void) 93{ 94 struct sk_buff *head = defer_kfree_skb_list; 95 96 defer_kfree_skb_list = NULL; 97 | 59#define RTNL_MAX_TYPE 50 60#define RTNL_SLAVE_MAX_TYPE 40 61 62struct rtnl_link { 63 rtnl_doit_func doit; 64 rtnl_dumpit_func dumpit; 65 struct module *owner; 66 unsigned int flags; --- 25 unchanged lines hidden (view full) --- 92EXPORT_SYMBOL(rtnl_kfree_skbs); 93 94void __rtnl_unlock(void) 95{ 96 struct sk_buff *head = defer_kfree_skb_list; 97 98 defer_kfree_skb_list = NULL; 99 |
100 /* Ensure that we didn't actually add any TODO item when __rtnl_unlock() 101 * is used. In some places, e.g. in cfg80211, we have code that will do 102 * something like 103 * rtnl_lock() 104 * wiphy_lock() 105 * ... 106 * rtnl_unlock() 107 * 108 * and because netdev_run_todo() acquires the RTNL for items on the list 109 * we could cause a situation such as this: 110 * Thread 1 Thread 2 111 * rtnl_lock() 112 * unregister_netdevice() 113 * __rtnl_unlock() 114 * rtnl_lock() 115 * wiphy_lock() 116 * rtnl_unlock() 117 * netdev_run_todo() 118 * __rtnl_unlock() 119 * 120 * // list not empty now 121 * // because of thread 2 122 * rtnl_lock() 123 * while (!list_empty(...)) 124 * rtnl_lock() 125 * wiphy_lock() 126 * **** DEADLOCK **** 127 * 128 * However, usage of __rtnl_unlock() is rare, and so we can ensure that 129 * it's not used in cases where something is added to do the list. 130 */ 131 WARN_ON(!list_empty(&net_todo_list)); 132 |
|
98 mutex_unlock(&rtnl_mutex); 99 100 while (head) { 101 struct sk_buff *next = head->next; 102 103 kfree_skb(head); 104 cond_resched(); 105 head = next; --- 103 unchanged lines hidden (view full) --- 209 210 WARN_ON(doit && link->doit && link->doit != doit); 211 if (doit) 212 link->doit = doit; 213 WARN_ON(dumpit && link->dumpit && link->dumpit != dumpit); 214 if (dumpit) 215 link->dumpit = dumpit; 216 | 133 mutex_unlock(&rtnl_mutex); 134 135 while (head) { 136 struct sk_buff *next = head->next; 137 138 kfree_skb(head); 139 cond_resched(); 140 head = next; --- 103 unchanged lines hidden (view full) --- 244 245 WARN_ON(doit && link->doit && link->doit != doit); 246 if (doit) 247 link->doit = doit; 248 WARN_ON(dumpit && link->dumpit && link->dumpit != dumpit); 249 if (dumpit) 250 link->dumpit = dumpit; 251 |
252 WARN_ON(rtnl_msgtype_kind(msgtype) != RTNL_KIND_DEL && 253 (flags & RTNL_FLAG_BULK_DEL_SUPPORTED)); |
|
217 link->flags |= flags; 218 219 /* publish protocol:msgtype */ 220 rcu_assign_pointer(tab[msgindex], link); 221 ret = 0; 222 if (old) 223 kfree_rcu(old, rcu); 224unlock: --- 2377 unchanged lines hidden (view full) --- 2602} 2603 2604#define DO_SETLINK_MODIFIED 0x01 2605/* notify flag means notify + modified. */ 2606#define DO_SETLINK_NOTIFY 0x03 2607static int do_setlink(const struct sk_buff *skb, 2608 struct net_device *dev, struct ifinfomsg *ifm, 2609 struct netlink_ext_ack *extack, | 254 link->flags |= flags; 255 256 /* publish protocol:msgtype */ 257 rcu_assign_pointer(tab[msgindex], link); 258 ret = 0; 259 if (old) 260 kfree_rcu(old, rcu); 261unlock: --- 2377 unchanged lines hidden (view full) --- 2639} 2640 2641#define DO_SETLINK_MODIFIED 0x01 2642/* notify flag means notify + modified. */ 2643#define DO_SETLINK_NOTIFY 0x03 2644static int do_setlink(const struct sk_buff *skb, 2645 struct net_device *dev, struct ifinfomsg *ifm, 2646 struct netlink_ext_ack *extack, |
2610 struct nlattr **tb, char *ifname, int status) | 2647 struct nlattr **tb, int status) |
2611{ 2612 const struct net_device_ops *ops = dev->netdev_ops; | 2648{ 2649 const struct net_device_ops *ops = dev->netdev_ops; |
2650 char ifname[IFNAMSIZ]; |
|
2613 int err; 2614 2615 err = validate_linkmsg(dev, tb, extack); 2616 if (err < 0) 2617 return err; 2618 | 2651 int err; 2652 2653 err = validate_linkmsg(dev, tb, extack); 2654 if (err < 0) 2655 return err; 2656 |
2657 if (tb[IFLA_IFNAME]) 2658 nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 2659 else 2660 ifname[0] = '\0'; 2661 |
|
2619 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) { | 2662 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD] || tb[IFLA_TARGET_NETNSID]) { |
2620 const char *pat = ifname && ifname[0] ? ifname : NULL; | 2663 const char *pat = ifname[0] ? ifname : NULL; |
2621 struct net *net; 2622 int new_ifindex; 2623 2624 net = rtnl_link_get_net_capable(skb, dev_net(dev), 2625 tb, CAP_NET_ADMIN); 2626 if (IS_ERR(net)) { 2627 err = PTR_ERR(net); 2628 goto errout; --- 126 unchanged lines hidden (view full) --- 2755 if (err) 2756 goto errout; 2757 status |= DO_SETLINK_MODIFIED; 2758 } 2759 2760 if (tb[IFLA_GSO_MAX_SIZE]) { 2761 u32 max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]); 2762 | 2664 struct net *net; 2665 int new_ifindex; 2666 2667 net = rtnl_link_get_net_capable(skb, dev_net(dev), 2668 tb, CAP_NET_ADMIN); 2669 if (IS_ERR(net)) { 2670 err = PTR_ERR(net); 2671 goto errout; --- 126 unchanged lines hidden (view full) --- 2798 if (err) 2799 goto errout; 2800 status |= DO_SETLINK_MODIFIED; 2801 } 2802 2803 if (tb[IFLA_GSO_MAX_SIZE]) { 2804 u32 max_size = nla_get_u32(tb[IFLA_GSO_MAX_SIZE]); 2805 |
2763 if (max_size > GSO_MAX_SIZE) { | 2806 if (max_size > GSO_MAX_SIZE || max_size > dev->tso_max_size) { |
2764 err = -EINVAL; 2765 goto errout; 2766 } 2767 2768 if (dev->gso_max_size ^ max_size) { 2769 netif_set_gso_max_size(dev, max_size); 2770 status |= DO_SETLINK_MODIFIED; 2771 } 2772 } 2773 2774 if (tb[IFLA_GSO_MAX_SEGS]) { 2775 u32 max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]); 2776 | 2807 err = -EINVAL; 2808 goto errout; 2809 } 2810 2811 if (dev->gso_max_size ^ max_size) { 2812 netif_set_gso_max_size(dev, max_size); 2813 status |= DO_SETLINK_MODIFIED; 2814 } 2815 } 2816 2817 if (tb[IFLA_GSO_MAX_SEGS]) { 2818 u32 max_segs = nla_get_u32(tb[IFLA_GSO_MAX_SEGS]); 2819 |
2777 if (max_segs > GSO_MAX_SEGS) { | 2820 if (max_segs > GSO_MAX_SEGS || max_segs > dev->tso_max_segs) { |
2778 err = -EINVAL; 2779 goto errout; 2780 } 2781 2782 if (dev->gso_max_segs ^ max_segs) { 2783 netif_set_gso_max_segs(dev, max_segs); 2784 status |= DO_SETLINK_MODIFIED; 2785 } --- 182 unchanged lines hidden (view full) --- 2968 net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n", 2969 dev->name); 2970 } 2971 2972 return err; 2973} 2974 2975static struct net_device *rtnl_dev_get(struct net *net, | 2821 err = -EINVAL; 2822 goto errout; 2823 } 2824 2825 if (dev->gso_max_segs ^ max_segs) { 2826 netif_set_gso_max_segs(dev, max_segs); 2827 status |= DO_SETLINK_MODIFIED; 2828 } --- 182 unchanged lines hidden (view full) --- 3011 net_warn_ratelimited("A link change request failed with some changes committed already. Interface %s may have been left with an inconsistent configuration, please check.\n", 3012 dev->name); 3013 } 3014 3015 return err; 3016} 3017 3018static struct net_device *rtnl_dev_get(struct net *net, |
2976 struct nlattr *ifname_attr, 2977 struct nlattr *altifname_attr, 2978 char *ifname) | 3019 struct nlattr *tb[]) |
2979{ | 3020{ |
2980 char buffer[ALTIFNAMSIZ]; | 3021 char ifname[ALTIFNAMSIZ]; |
2981 | 3022 |
2982 if (!ifname) { 2983 ifname = buffer; 2984 if (ifname_attr) 2985 nla_strscpy(ifname, ifname_attr, IFNAMSIZ); 2986 else if (altifname_attr) 2987 nla_strscpy(ifname, altifname_attr, ALTIFNAMSIZ); 2988 else 2989 return NULL; 2990 } | 3023 if (tb[IFLA_IFNAME]) 3024 nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 3025 else if (tb[IFLA_ALT_IFNAME]) 3026 nla_strscpy(ifname, tb[IFLA_ALT_IFNAME], ALTIFNAMSIZ); 3027 else 3028 return NULL; |
2991 2992 return __dev_get_by_name(net, ifname); 2993} 2994 2995static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, 2996 struct netlink_ext_ack *extack) 2997{ 2998 struct net *net = sock_net(skb->sk); 2999 struct ifinfomsg *ifm; 3000 struct net_device *dev; 3001 int err; 3002 struct nlattr *tb[IFLA_MAX+1]; | 3029 3030 return __dev_get_by_name(net, ifname); 3031} 3032 3033static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, 3034 struct netlink_ext_ack *extack) 3035{ 3036 struct net *net = sock_net(skb->sk); 3037 struct ifinfomsg *ifm; 3038 struct net_device *dev; 3039 int err; 3040 struct nlattr *tb[IFLA_MAX+1]; |
3003 char ifname[IFNAMSIZ]; | |
3004 3005 err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX, 3006 ifla_policy, extack); 3007 if (err < 0) 3008 goto errout; 3009 3010 err = rtnl_ensure_unique_netns(tb, extack, false); 3011 if (err < 0) 3012 goto errout; 3013 | 3041 3042 err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX, 3043 ifla_policy, extack); 3044 if (err < 0) 3045 goto errout; 3046 3047 err = rtnl_ensure_unique_netns(tb, extack, false); 3048 if (err < 0) 3049 goto errout; 3050 |
3014 if (tb[IFLA_IFNAME]) 3015 nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 3016 else 3017 ifname[0] = '\0'; 3018 | |
3019 err = -EINVAL; 3020 ifm = nlmsg_data(nlh); 3021 if (ifm->ifi_index > 0) 3022 dev = __dev_get_by_index(net, ifm->ifi_index); 3023 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) | 3051 err = -EINVAL; 3052 ifm = nlmsg_data(nlh); 3053 if (ifm->ifi_index > 0) 3054 dev = __dev_get_by_index(net, ifm->ifi_index); 3055 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) |
3024 dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname); | 3056 dev = rtnl_dev_get(net, tb); |
3025 else 3026 goto errout; 3027 3028 if (dev == NULL) { 3029 err = -ENODEV; 3030 goto errout; 3031 } 3032 | 3057 else 3058 goto errout; 3059 3060 if (dev == NULL) { 3061 err = -ENODEV; 3062 goto errout; 3063 } 3064 |
3033 err = do_setlink(skb, dev, ifm, extack, tb, ifname, 0); | 3065 err = do_setlink(skb, dev, ifm, extack, tb, 0); |
3034errout: 3035 return err; 3036} 3037 3038static int rtnl_group_dellink(const struct net *net, int group) 3039{ 3040 struct net_device *dev, *aux; 3041 LIST_HEAD(list_kill); --- 72 unchanged lines hidden (view full) --- 3114 return PTR_ERR(tgt_net); 3115 } 3116 3117 err = -EINVAL; 3118 ifm = nlmsg_data(nlh); 3119 if (ifm->ifi_index > 0) 3120 dev = __dev_get_by_index(tgt_net, ifm->ifi_index); 3121 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) | 3066errout: 3067 return err; 3068} 3069 3070static int rtnl_group_dellink(const struct net *net, int group) 3071{ 3072 struct net_device *dev, *aux; 3073 LIST_HEAD(list_kill); --- 72 unchanged lines hidden (view full) --- 3146 return PTR_ERR(tgt_net); 3147 } 3148 3149 err = -EINVAL; 3150 ifm = nlmsg_data(nlh); 3151 if (ifm->ifi_index > 0) 3152 dev = __dev_get_by_index(tgt_net, ifm->ifi_index); 3153 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) |
3122 dev = rtnl_dev_get(net, tb[IFLA_IFNAME], 3123 tb[IFLA_ALT_IFNAME], NULL); | 3154 dev = rtnl_dev_get(net, tb); |
3124 else if (tb[IFLA_GROUP]) 3125 err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP])); 3126 else 3127 goto out; 3128 3129 if (!dev) { | 3155 else if (tb[IFLA_GROUP]) 3156 err = rtnl_group_dellink(tgt_net, nla_get_u32(tb[IFLA_GROUP])); 3157 else 3158 goto out; 3159 3160 if (!dev) { |
3130 if (tb[IFLA_IFNAME] || ifm->ifi_index > 0) | 3161 if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME] || ifm->ifi_index > 0) |
3131 err = -ENODEV; 3132 3133 goto out; 3134 } 3135 3136 err = rtnl_delete_link(dev); 3137 3138out: --- 118 unchanged lines hidden (view full) --- 3257 struct netlink_ext_ack *extack, 3258 struct nlattr **tb) 3259{ 3260 struct net_device *dev, *aux; 3261 int err; 3262 3263 for_each_netdev_safe(net, dev, aux) { 3264 if (dev->group == group) { | 3162 err = -ENODEV; 3163 3164 goto out; 3165 } 3166 3167 err = rtnl_delete_link(dev); 3168 3169out: --- 118 unchanged lines hidden (view full) --- 3288 struct netlink_ext_ack *extack, 3289 struct nlattr **tb) 3290{ 3291 struct net_device *dev, *aux; 3292 int err; 3293 3294 for_each_netdev_safe(net, dev, aux) { 3295 if (dev->group == group) { |
3265 err = do_setlink(skb, dev, ifm, extack, tb, NULL, 0); | 3296 err = do_setlink(skb, dev, ifm, extack, tb, 0); |
3266 if (err < 0) 3267 return err; 3268 } 3269 } 3270 3271 return 0; 3272} 3273 | 3297 if (err < 0) 3298 return err; 3299 } 3300 } 3301 3302 return 0; 3303} 3304 |
3274static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, 3275 struct nlattr **attr, struct netlink_ext_ack *extack) | 3305static int rtnl_newlink_create(struct sk_buff *skb, struct ifinfomsg *ifm, 3306 const struct rtnl_link_ops *ops, 3307 struct nlattr **tb, struct nlattr **data, 3308 struct netlink_ext_ack *extack) |
3276{ | 3309{ |
3277 struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1]; | |
3278 unsigned char name_assign_type = NET_NAME_USER; | 3310 unsigned char name_assign_type = NET_NAME_USER; |
3311 struct net *net = sock_net(skb->sk); 3312 struct net *dest_net, *link_net; 3313 struct net_device *dev; 3314 char ifname[IFNAMSIZ]; 3315 int err; 3316 3317 if (!ops->alloc && !ops->setup) 3318 return -EOPNOTSUPP; 3319 3320 if (tb[IFLA_IFNAME]) { 3321 nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 3322 } else { 3323 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); 3324 name_assign_type = NET_NAME_ENUM; 3325 } 3326 3327 dest_net = rtnl_link_get_net_capable(skb, net, tb, CAP_NET_ADMIN); 3328 if (IS_ERR(dest_net)) 3329 return PTR_ERR(dest_net); 3330 3331 if (tb[IFLA_LINK_NETNSID]) { 3332 int id = nla_get_s32(tb[IFLA_LINK_NETNSID]); 3333 3334 link_net = get_net_ns_by_id(dest_net, id); 3335 if (!link_net) { 3336 NL_SET_ERR_MSG(extack, "Unknown network namespace id"); 3337 err = -EINVAL; 3338 goto out; 3339 } 3340 err = -EPERM; 3341 if (!netlink_ns_capable(skb, link_net->user_ns, CAP_NET_ADMIN)) 3342 goto out; 3343 } else { 3344 link_net = NULL; 3345 } 3346 3347 dev = rtnl_create_link(link_net ? : dest_net, ifname, 3348 name_assign_type, ops, tb, extack); 3349 if (IS_ERR(dev)) { 3350 err = PTR_ERR(dev); 3351 goto out; 3352 } 3353 3354 dev->ifindex = ifm->ifi_index; 3355 3356 if (ops->newlink) 3357 err = ops->newlink(link_net ? : net, dev, tb, data, extack); 3358 else 3359 err = register_netdevice(dev); 3360 if (err < 0) { 3361 free_netdev(dev); 3362 goto out; 3363 } 3364 3365 err = rtnl_configure_link(dev, ifm); 3366 if (err < 0) 3367 goto out_unregister; 3368 if (link_net) { 3369 err = dev_change_net_namespace(dev, dest_net, ifname); 3370 if (err < 0) 3371 goto out_unregister; 3372 } 3373 if (tb[IFLA_MASTER]) { 3374 err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack); 3375 if (err) 3376 goto out_unregister; 3377 } 3378out: 3379 if (link_net) 3380 put_net(link_net); 3381 put_net(dest_net); 3382 return err; 3383out_unregister: 3384 if (ops->newlink) { 3385 LIST_HEAD(list_kill); 3386 3387 ops->dellink(dev, &list_kill); 3388 unregister_netdevice_many(&list_kill); 3389 } else { 3390 unregister_netdevice(dev); 3391 } 3392 goto out; 3393} 3394 3395struct rtnl_newlink_tbs { 3396 struct nlattr *tb[IFLA_MAX + 1]; 3397 struct nlattr *attr[RTNL_MAX_TYPE + 1]; 3398 struct nlattr *slave_attr[RTNL_SLAVE_MAX_TYPE + 1]; 3399}; 3400 3401static int __rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, 3402 struct rtnl_newlink_tbs *tbs, 3403 struct netlink_ext_ack *extack) 3404{ |
|
3279 struct nlattr *linkinfo[IFLA_INFO_MAX + 1]; | 3405 struct nlattr *linkinfo[IFLA_INFO_MAX + 1]; |
3406 struct nlattr ** const tb = tbs->tb; |
|
3280 const struct rtnl_link_ops *m_ops; 3281 struct net_device *master_dev; 3282 struct net *net = sock_net(skb->sk); 3283 const struct rtnl_link_ops *ops; | 3407 const struct rtnl_link_ops *m_ops; 3408 struct net_device *master_dev; 3409 struct net *net = sock_net(skb->sk); 3410 const struct rtnl_link_ops *ops; |
3284 struct nlattr *tb[IFLA_MAX + 1]; 3285 struct net *dest_net, *link_net; | |
3286 struct nlattr **slave_data; 3287 char kind[MODULE_NAME_LEN]; 3288 struct net_device *dev; 3289 struct ifinfomsg *ifm; | 3411 struct nlattr **slave_data; 3412 char kind[MODULE_NAME_LEN]; 3413 struct net_device *dev; 3414 struct ifinfomsg *ifm; |
3290 char ifname[IFNAMSIZ]; | |
3291 struct nlattr **data; | 3415 struct nlattr **data; |
3416 bool link_specified; |
|
3292 int err; 3293 3294#ifdef CONFIG_MODULES 3295replay: 3296#endif 3297 err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX, 3298 ifla_policy, extack); 3299 if (err < 0) 3300 return err; 3301 3302 err = rtnl_ensure_unique_netns(tb, extack, false); 3303 if (err < 0) 3304 return err; 3305 | 3417 int err; 3418 3419#ifdef CONFIG_MODULES 3420replay: 3421#endif 3422 err = nlmsg_parse_deprecated(nlh, sizeof(*ifm), tb, IFLA_MAX, 3423 ifla_policy, extack); 3424 if (err < 0) 3425 return err; 3426 3427 err = rtnl_ensure_unique_netns(tb, extack, false); 3428 if (err < 0) 3429 return err; 3430 |
3306 if (tb[IFLA_IFNAME]) 3307 nla_strscpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ); 3308 else 3309 ifname[0] = '\0'; 3310 | |
3311 ifm = nlmsg_data(nlh); | 3431 ifm = nlmsg_data(nlh); |
3312 if (ifm->ifi_index > 0) | 3432 if (ifm->ifi_index > 0) { 3433 link_specified = true; |
3313 dev = __dev_get_by_index(net, ifm->ifi_index); | 3434 dev = __dev_get_by_index(net, ifm->ifi_index); |
3314 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) 3315 dev = rtnl_dev_get(net, NULL, tb[IFLA_ALT_IFNAME], ifname); 3316 else | 3435 } else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) { 3436 link_specified = true; 3437 dev = rtnl_dev_get(net, tb); 3438 } else { 3439 link_specified = false; |
3317 dev = NULL; | 3440 dev = NULL; |
3441 } |
|
3318 3319 master_dev = NULL; 3320 m_ops = NULL; 3321 if (dev) { 3322 master_dev = netdev_master_upper_dev_get(dev); 3323 if (master_dev) 3324 m_ops = master_dev->rtnl_link_ops; 3325 } --- 20 unchanged lines hidden (view full) --- 3346 } 3347 3348 data = NULL; 3349 if (ops) { 3350 if (ops->maxtype > RTNL_MAX_TYPE) 3351 return -EINVAL; 3352 3353 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) { | 3442 3443 master_dev = NULL; 3444 m_ops = NULL; 3445 if (dev) { 3446 master_dev = netdev_master_upper_dev_get(dev); 3447 if (master_dev) 3448 m_ops = master_dev->rtnl_link_ops; 3449 } --- 20 unchanged lines hidden (view full) --- 3470 } 3471 3472 data = NULL; 3473 if (ops) { 3474 if (ops->maxtype > RTNL_MAX_TYPE) 3475 return -EINVAL; 3476 3477 if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) { |
3354 err = nla_parse_nested_deprecated(attr, ops->maxtype, | 3478 err = nla_parse_nested_deprecated(tbs->attr, ops->maxtype, |
3355 linkinfo[IFLA_INFO_DATA], 3356 ops->policy, extack); 3357 if (err < 0) 3358 return err; | 3479 linkinfo[IFLA_INFO_DATA], 3480 ops->policy, extack); 3481 if (err < 0) 3482 return err; |
3359 data = attr; | 3483 data = tbs->attr; |
3360 } 3361 if (ops->validate) { 3362 err = ops->validate(tb, data, extack); 3363 if (err < 0) 3364 return err; 3365 } 3366 } 3367 3368 slave_data = NULL; 3369 if (m_ops) { 3370 if (m_ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE) 3371 return -EINVAL; 3372 3373 if (m_ops->slave_maxtype && 3374 linkinfo[IFLA_INFO_SLAVE_DATA]) { | 3484 } 3485 if (ops->validate) { 3486 err = ops->validate(tb, data, extack); 3487 if (err < 0) 3488 return err; 3489 } 3490 } 3491 3492 slave_data = NULL; 3493 if (m_ops) { 3494 if (m_ops->slave_maxtype > RTNL_SLAVE_MAX_TYPE) 3495 return -EINVAL; 3496 3497 if (m_ops->slave_maxtype && 3498 linkinfo[IFLA_INFO_SLAVE_DATA]) { |
3375 err = nla_parse_nested_deprecated(slave_attr, | 3499 err = nla_parse_nested_deprecated(tbs->slave_attr, |
3376 m_ops->slave_maxtype, 3377 linkinfo[IFLA_INFO_SLAVE_DATA], 3378 m_ops->slave_policy, 3379 extack); 3380 if (err < 0) 3381 return err; | 3500 m_ops->slave_maxtype, 3501 linkinfo[IFLA_INFO_SLAVE_DATA], 3502 m_ops->slave_policy, 3503 extack); 3504 if (err < 0) 3505 return err; |
3382 slave_data = slave_attr; | 3506 slave_data = tbs->slave_attr; |
3383 } 3384 } 3385 3386 if (dev) { 3387 int status = 0; 3388 3389 if (nlh->nlmsg_flags & NLM_F_EXCL) 3390 return -EEXIST; --- 17 unchanged lines hidden (view full) --- 3408 3409 err = m_ops->slave_changelink(master_dev, dev, tb, 3410 slave_data, extack); 3411 if (err < 0) 3412 return err; 3413 status |= DO_SETLINK_NOTIFY; 3414 } 3415 | 3507 } 3508 } 3509 3510 if (dev) { 3511 int status = 0; 3512 3513 if (nlh->nlmsg_flags & NLM_F_EXCL) 3514 return -EEXIST; --- 17 unchanged lines hidden (view full) --- 3532 3533 err = m_ops->slave_changelink(master_dev, dev, tb, 3534 slave_data, extack); 3535 if (err < 0) 3536 return err; 3537 status |= DO_SETLINK_NOTIFY; 3538 } 3539 |
3416 return do_setlink(skb, dev, ifm, extack, tb, ifname, status); | 3540 return do_setlink(skb, dev, ifm, extack, tb, status); |
3417 } 3418 3419 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { | 3541 } 3542 3543 if (!(nlh->nlmsg_flags & NLM_F_CREATE)) { |
3420 if (ifm->ifi_index == 0 && tb[IFLA_GROUP]) | 3544 /* No dev found and NLM_F_CREATE not set. Requested dev does not exist, 3545 * or it's for a group 3546 */ 3547 if (link_specified) 3548 return -ENODEV; 3549 if (tb[IFLA_GROUP]) |
3421 return rtnl_group_changelink(skb, net, 3422 nla_get_u32(tb[IFLA_GROUP]), 3423 ifm, extack, tb); 3424 return -ENODEV; 3425 } 3426 3427 if (tb[IFLA_MAP] || tb[IFLA_PROTINFO]) 3428 return -EOPNOTSUPP; --- 8 unchanged lines hidden (view full) --- 3437 if (ops) 3438 goto replay; 3439 } 3440#endif 3441 NL_SET_ERR_MSG(extack, "Unknown device type"); 3442 return -EOPNOTSUPP; 3443 } 3444 | 3550 return rtnl_group_changelink(skb, net, 3551 nla_get_u32(tb[IFLA_GROUP]), 3552 ifm, extack, tb); 3553 return -ENODEV; 3554 } 3555 3556 if (tb[IFLA_MAP] || tb[IFLA_PROTINFO]) 3557 return -EOPNOTSUPP; --- 8 unchanged lines hidden (view full) --- 3566 if (ops) 3567 goto replay; 3568 } 3569#endif 3570 NL_SET_ERR_MSG(extack, "Unknown device type"); 3571 return -EOPNOTSUPP; 3572 } 3573 |
3445 if (!ops->alloc && !ops->setup) 3446 return -EOPNOTSUPP; 3447 3448 if (!ifname[0]) { 3449 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind); 3450 name_assign_type = NET_NAME_ENUM; 3451 } 3452 3453 dest_net = rtnl_link_get_net_capable(skb, net, tb, CAP_NET_ADMIN); 3454 if (IS_ERR(dest_net)) 3455 return PTR_ERR(dest_net); 3456 3457 if (tb[IFLA_LINK_NETNSID]) { 3458 int id = nla_get_s32(tb[IFLA_LINK_NETNSID]); 3459 3460 link_net = get_net_ns_by_id(dest_net, id); 3461 if (!link_net) { 3462 NL_SET_ERR_MSG(extack, "Unknown network namespace id"); 3463 err = -EINVAL; 3464 goto out; 3465 } 3466 err = -EPERM; 3467 if (!netlink_ns_capable(skb, link_net->user_ns, CAP_NET_ADMIN)) 3468 goto out; 3469 } else { 3470 link_net = NULL; 3471 } 3472 3473 dev = rtnl_create_link(link_net ? : dest_net, ifname, 3474 name_assign_type, ops, tb, extack); 3475 if (IS_ERR(dev)) { 3476 err = PTR_ERR(dev); 3477 goto out; 3478 } 3479 3480 dev->ifindex = ifm->ifi_index; 3481 3482 if (ops->newlink) 3483 err = ops->newlink(link_net ? : net, dev, tb, data, extack); 3484 else 3485 err = register_netdevice(dev); 3486 if (err < 0) { 3487 free_netdev(dev); 3488 goto out; 3489 } 3490 3491 err = rtnl_configure_link(dev, ifm); 3492 if (err < 0) 3493 goto out_unregister; 3494 if (link_net) { 3495 err = dev_change_net_namespace(dev, dest_net, ifname); 3496 if (err < 0) 3497 goto out_unregister; 3498 } 3499 if (tb[IFLA_MASTER]) { 3500 err = do_set_master(dev, nla_get_u32(tb[IFLA_MASTER]), extack); 3501 if (err) 3502 goto out_unregister; 3503 } 3504out: 3505 if (link_net) 3506 put_net(link_net); 3507 put_net(dest_net); 3508 return err; 3509out_unregister: 3510 if (ops->newlink) { 3511 LIST_HEAD(list_kill); 3512 3513 ops->dellink(dev, &list_kill); 3514 unregister_netdevice_many(&list_kill); 3515 } else { 3516 unregister_netdevice(dev); 3517 } 3518 goto out; | 3574 return rtnl_newlink_create(skb, ifm, ops, tb, data, extack); |
3519} 3520 3521static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, 3522 struct netlink_ext_ack *extack) 3523{ | 3575} 3576 3577static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, 3578 struct netlink_ext_ack *extack) 3579{ |
3524 struct nlattr **attr; | 3580 struct rtnl_newlink_tbs *tbs; |
3525 int ret; 3526 | 3581 int ret; 3582 |
3527 attr = kmalloc_array(RTNL_MAX_TYPE + 1, sizeof(*attr), GFP_KERNEL); 3528 if (!attr) | 3583 tbs = kmalloc(sizeof(*tbs), GFP_KERNEL); 3584 if (!tbs) |
3529 return -ENOMEM; 3530 | 3585 return -ENOMEM; 3586 |
3531 ret = __rtnl_newlink(skb, nlh, attr, extack); 3532 kfree(attr); | 3587 ret = __rtnl_newlink(skb, nlh, tbs, extack); 3588 kfree(tbs); |
3533 return ret; 3534} 3535 3536static int rtnl_valid_getlink_req(struct sk_buff *skb, 3537 const struct nlmsghdr *nlh, 3538 struct nlattr **tb, 3539 struct netlink_ext_ack *extack) 3540{ --- 71 unchanged lines hidden (view full) --- 3612 if (tb[IFLA_EXT_MASK]) 3613 ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); 3614 3615 err = -EINVAL; 3616 ifm = nlmsg_data(nlh); 3617 if (ifm->ifi_index > 0) 3618 dev = __dev_get_by_index(tgt_net, ifm->ifi_index); 3619 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) | 3589 return ret; 3590} 3591 3592static int rtnl_valid_getlink_req(struct sk_buff *skb, 3593 const struct nlmsghdr *nlh, 3594 struct nlattr **tb, 3595 struct netlink_ext_ack *extack) 3596{ --- 71 unchanged lines hidden (view full) --- 3668 if (tb[IFLA_EXT_MASK]) 3669 ext_filter_mask = nla_get_u32(tb[IFLA_EXT_MASK]); 3670 3671 err = -EINVAL; 3672 ifm = nlmsg_data(nlh); 3673 if (ifm->ifi_index > 0) 3674 dev = __dev_get_by_index(tgt_net, ifm->ifi_index); 3675 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) |
3620 dev = rtnl_dev_get(tgt_net, tb[IFLA_IFNAME], 3621 tb[IFLA_ALT_IFNAME], NULL); | 3676 dev = rtnl_dev_get(tgt_net, tb); |
3622 else 3623 goto out; 3624 3625 err = -ENODEV; 3626 if (dev == NULL) 3627 goto out; 3628 3629 err = -ENOBUFS; --- 78 unchanged lines hidden (view full) --- 3708 err = rtnl_ensure_unique_netns(tb, extack, true); 3709 if (err) 3710 return err; 3711 3712 ifm = nlmsg_data(nlh); 3713 if (ifm->ifi_index > 0) 3714 dev = __dev_get_by_index(net, ifm->ifi_index); 3715 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) | 3677 else 3678 goto out; 3679 3680 err = -ENODEV; 3681 if (dev == NULL) 3682 goto out; 3683 3684 err = -ENOBUFS; --- 78 unchanged lines hidden (view full) --- 3763 err = rtnl_ensure_unique_netns(tb, extack, true); 3764 if (err) 3765 return err; 3766 3767 ifm = nlmsg_data(nlh); 3768 if (ifm->ifi_index > 0) 3769 dev = __dev_get_by_index(net, ifm->ifi_index); 3770 else if (tb[IFLA_IFNAME] || tb[IFLA_ALT_IFNAME]) |
3716 dev = rtnl_dev_get(net, tb[IFLA_IFNAME], 3717 tb[IFLA_ALT_IFNAME], NULL); | 3771 dev = rtnl_dev_get(net, tb); |
3718 else 3719 return -EINVAL; 3720 3721 if (!dev) 3722 return -ENODEV; 3723 3724 if (!tb[IFLA_PROP_LIST]) 3725 return 0; --- 401 unchanged lines hidden (view full) --- 4127 err = dev_uc_del(dev, addr); 4128 else if (is_multicast_ether_addr(addr)) 4129 err = dev_mc_del(dev, addr); 4130 4131 return err; 4132} 4133EXPORT_SYMBOL(ndo_dflt_fdb_del); 4134 | 3772 else 3773 return -EINVAL; 3774 3775 if (!dev) 3776 return -ENODEV; 3777 3778 if (!tb[IFLA_PROP_LIST]) 3779 return 0; --- 401 unchanged lines hidden (view full) --- 4181 err = dev_uc_del(dev, addr); 4182 else if (is_multicast_ether_addr(addr)) 4183 err = dev_mc_del(dev, addr); 4184 4185 return err; 4186} 4187EXPORT_SYMBOL(ndo_dflt_fdb_del); 4188 |
4189static const struct nla_policy fdb_del_bulk_policy[NDA_MAX + 1] = { 4190 [NDA_VLAN] = { .type = NLA_U16 }, 4191 [NDA_IFINDEX] = NLA_POLICY_MIN(NLA_S32, 1), 4192 [NDA_NDM_STATE_MASK] = { .type = NLA_U16 }, 4193 [NDA_NDM_FLAGS_MASK] = { .type = NLA_U8 }, 4194}; 4195 |
|
4135static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, 4136 struct netlink_ext_ack *extack) 4137{ | 4196static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh, 4197 struct netlink_ext_ack *extack) 4198{ |
4199 bool del_bulk = !!(nlh->nlmsg_flags & NLM_F_BULK); |
|
4138 struct net *net = sock_net(skb->sk); | 4200 struct net *net = sock_net(skb->sk); |
4201 const struct net_device_ops *ops; |
|
4139 struct ndmsg *ndm; 4140 struct nlattr *tb[NDA_MAX+1]; 4141 struct net_device *dev; | 4202 struct ndmsg *ndm; 4203 struct nlattr *tb[NDA_MAX+1]; 4204 struct net_device *dev; |
4142 __u8 *addr; | 4205 __u8 *addr = NULL; |
4143 int err; 4144 u16 vid; 4145 4146 if (!netlink_capable(skb, CAP_NET_ADMIN)) 4147 return -EPERM; 4148 | 4206 int err; 4207 u16 vid; 4208 4209 if (!netlink_capable(skb, CAP_NET_ADMIN)) 4210 return -EPERM; 4211 |
4149 err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, NULL, 4150 extack); | 4212 if (!del_bulk) { 4213 err = nlmsg_parse_deprecated(nlh, sizeof(*ndm), tb, NDA_MAX, 4214 NULL, extack); 4215 } else { 4216 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, 4217 fdb_del_bulk_policy, extack); 4218 } |
4151 if (err < 0) 4152 return err; 4153 4154 ndm = nlmsg_data(nlh); 4155 if (ndm->ndm_ifindex == 0) { 4156 NL_SET_ERR_MSG(extack, "invalid ifindex"); 4157 return -EINVAL; 4158 } 4159 4160 dev = __dev_get_by_index(net, ndm->ndm_ifindex); 4161 if (dev == NULL) { 4162 NL_SET_ERR_MSG(extack, "unknown ifindex"); 4163 return -ENODEV; 4164 } 4165 | 4219 if (err < 0) 4220 return err; 4221 4222 ndm = nlmsg_data(nlh); 4223 if (ndm->ndm_ifindex == 0) { 4224 NL_SET_ERR_MSG(extack, "invalid ifindex"); 4225 return -EINVAL; 4226 } 4227 4228 dev = __dev_get_by_index(net, ndm->ndm_ifindex); 4229 if (dev == NULL) { 4230 NL_SET_ERR_MSG(extack, "unknown ifindex"); 4231 return -ENODEV; 4232 } 4233 |
4166 if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { 4167 NL_SET_ERR_MSG(extack, "invalid address"); 4168 return -EINVAL; | 4234 if (!del_bulk) { 4235 if (!tb[NDA_LLADDR] || nla_len(tb[NDA_LLADDR]) != ETH_ALEN) { 4236 NL_SET_ERR_MSG(extack, "invalid address"); 4237 return -EINVAL; 4238 } 4239 addr = nla_data(tb[NDA_LLADDR]); |
4169 } 4170 4171 if (dev->type != ARPHRD_ETHER) { 4172 NL_SET_ERR_MSG(extack, "FDB delete only supported for Ethernet devices"); 4173 return -EINVAL; 4174 } 4175 | 4240 } 4241 4242 if (dev->type != ARPHRD_ETHER) { 4243 NL_SET_ERR_MSG(extack, "FDB delete only supported for Ethernet devices"); 4244 return -EINVAL; 4245 } 4246 |
4176 addr = nla_data(tb[NDA_LLADDR]); 4177 | |
4178 err = fdb_vid_parse(tb[NDA_VLAN], &vid, extack); 4179 if (err) 4180 return err; 4181 4182 err = -EOPNOTSUPP; 4183 4184 /* Support fdb on master device the net/bridge default case */ 4185 if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && 4186 netif_is_bridge_port(dev)) { 4187 struct net_device *br_dev = netdev_master_upper_dev_get(dev); | 4247 err = fdb_vid_parse(tb[NDA_VLAN], &vid, extack); 4248 if (err) 4249 return err; 4250 4251 err = -EOPNOTSUPP; 4252 4253 /* Support fdb on master device the net/bridge default case */ 4254 if ((!ndm->ndm_flags || ndm->ndm_flags & NTF_MASTER) && 4255 netif_is_bridge_port(dev)) { 4256 struct net_device *br_dev = netdev_master_upper_dev_get(dev); |
4188 const struct net_device_ops *ops = br_dev->netdev_ops; | |
4189 | 4257 |
4190 if (ops->ndo_fdb_del) 4191 err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); | 4258 ops = br_dev->netdev_ops; 4259 if (!del_bulk) { 4260 if (ops->ndo_fdb_del) 4261 err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); 4262 } else { 4263 if (ops->ndo_fdb_del_bulk) 4264 err = ops->ndo_fdb_del_bulk(ndm, tb, dev, vid, 4265 extack); 4266 } |
4192 4193 if (err) 4194 goto out; 4195 else 4196 ndm->ndm_flags &= ~NTF_MASTER; 4197 } 4198 4199 /* Embedded bridge, macvlan, and any other device support */ 4200 if (ndm->ndm_flags & NTF_SELF) { | 4267 4268 if (err) 4269 goto out; 4270 else 4271 ndm->ndm_flags &= ~NTF_MASTER; 4272 } 4273 4274 /* Embedded bridge, macvlan, and any other device support */ 4275 if (ndm->ndm_flags & NTF_SELF) { |
4201 if (dev->netdev_ops->ndo_fdb_del) 4202 err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr, 4203 vid); 4204 else 4205 err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); | 4276 ops = dev->netdev_ops; 4277 if (!del_bulk) { 4278 if (ops->ndo_fdb_del) 4279 err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid); 4280 else 4281 err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid); 4282 } else { 4283 /* in case err was cleared by NTF_MASTER call */ 4284 err = -EOPNOTSUPP; 4285 if (ops->ndo_fdb_del_bulk) 4286 err = ops->ndo_fdb_del_bulk(ndm, tb, dev, vid, 4287 extack); 4288 } |
4206 4207 if (!err) { | 4289 4290 if (!err) { |
4208 rtnl_fdb_notify(dev, addr, vid, RTM_DELNEIGH, 4209 ndm->ndm_state); | 4291 if (!del_bulk) 4292 rtnl_fdb_notify(dev, addr, vid, RTM_DELNEIGH, 4293 ndm->ndm_state); |
4210 ndm->ndm_flags &= ~NTF_SELF; 4211 } 4212 } 4213out: 4214 return err; 4215} 4216 4217static int nlmsg_populate_fdb(struct sk_buff *skb, --- 1673 unchanged lines hidden (view full) --- 5891 5892/* Process one rtnetlink message. */ 5893 5894static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 5895 struct netlink_ext_ack *extack) 5896{ 5897 struct net *net = sock_net(skb->sk); 5898 struct rtnl_link *link; | 4294 ndm->ndm_flags &= ~NTF_SELF; 4295 } 4296 } 4297out: 4298 return err; 4299} 4300 4301static int nlmsg_populate_fdb(struct sk_buff *skb, --- 1673 unchanged lines hidden (view full) --- 5975 5976/* Process one rtnetlink message. */ 5977 5978static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh, 5979 struct netlink_ext_ack *extack) 5980{ 5981 struct net *net = sock_net(skb->sk); 5982 struct rtnl_link *link; |
5983 enum rtnl_kinds kind; |
|
5899 struct module *owner; 5900 int err = -EOPNOTSUPP; 5901 rtnl_doit_func doit; 5902 unsigned int flags; | 5984 struct module *owner; 5985 int err = -EOPNOTSUPP; 5986 rtnl_doit_func doit; 5987 unsigned int flags; |
5903 int kind; | |
5904 int family; 5905 int type; 5906 5907 type = nlh->nlmsg_type; 5908 if (type > RTM_MAX) 5909 return -EOPNOTSUPP; 5910 5911 type -= RTM_BASE; 5912 5913 /* All the messages must have at least 1 byte length */ 5914 if (nlmsg_len(nlh) < sizeof(struct rtgenmsg)) 5915 return 0; 5916 5917 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; | 5988 int family; 5989 int type; 5990 5991 type = nlh->nlmsg_type; 5992 if (type > RTM_MAX) 5993 return -EOPNOTSUPP; 5994 5995 type -= RTM_BASE; 5996 5997 /* All the messages must have at least 1 byte length */ 5998 if (nlmsg_len(nlh) < sizeof(struct rtgenmsg)) 5999 return 0; 6000 6001 family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family; |
5918 kind = type&3; | 6002 kind = rtnl_msgtype_kind(type); |
5919 | 6003 |
5920 if (kind != 2 && !netlink_net_capable(skb, CAP_NET_ADMIN)) | 6004 if (kind != RTNL_KIND_GET && !netlink_net_capable(skb, CAP_NET_ADMIN)) |
5921 return -EPERM; 5922 5923 rcu_read_lock(); | 6005 return -EPERM; 6006 6007 rcu_read_lock(); |
5924 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) { | 6008 if (kind == RTNL_KIND_GET && (nlh->nlmsg_flags & NLM_F_DUMP)) { |
5925 struct sock *rtnl; 5926 rtnl_dumpit_func dumpit; 5927 u32 min_dump_alloc = 0; 5928 5929 link = rtnl_get_link(family, type); 5930 if (!link || !link->dumpit) { 5931 family = PF_UNSPEC; 5932 link = rtnl_get_link(family, type); --- 39 unchanged lines hidden (view full) --- 5972 5973 owner = link->owner; 5974 if (!try_module_get(owner)) { 5975 err = -EPROTONOSUPPORT; 5976 goto out_unlock; 5977 } 5978 5979 flags = link->flags; | 6009 struct sock *rtnl; 6010 rtnl_dumpit_func dumpit; 6011 u32 min_dump_alloc = 0; 6012 6013 link = rtnl_get_link(family, type); 6014 if (!link || !link->dumpit) { 6015 family = PF_UNSPEC; 6016 link = rtnl_get_link(family, type); --- 39 unchanged lines hidden (view full) --- 6056 6057 owner = link->owner; 6058 if (!try_module_get(owner)) { 6059 err = -EPROTONOSUPPORT; 6060 goto out_unlock; 6061 } 6062 6063 flags = link->flags; |
6064 if (kind == RTNL_KIND_DEL && (nlh->nlmsg_flags & NLM_F_BULK) && 6065 !(flags & RTNL_FLAG_BULK_DEL_SUPPORTED)) { 6066 NL_SET_ERR_MSG(extack, "Bulk delete is not supported"); 6067 goto err_unlock; 6068 } 6069 |
|
5980 if (flags & RTNL_FLAG_DOIT_UNLOCKED) { 5981 doit = link->doit; 5982 rcu_read_unlock(); 5983 if (doit) 5984 err = doit(skb, nlh, extack); 5985 module_put(owner); 5986 return err; 5987 } --- 112 unchanged lines hidden (view full) --- 6100 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, 0); 6101 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0); 6102 rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0); 6103 6104 rtnl_register(PF_UNSPEC, RTM_NEWLINKPROP, rtnl_newlinkprop, NULL, 0); 6105 rtnl_register(PF_UNSPEC, RTM_DELLINKPROP, rtnl_dellinkprop, NULL, 0); 6106 6107 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0); | 6070 if (flags & RTNL_FLAG_DOIT_UNLOCKED) { 6071 doit = link->doit; 6072 rcu_read_unlock(); 6073 if (doit) 6074 err = doit(skb, nlh, extack); 6075 module_put(owner); 6076 return err; 6077 } --- 112 unchanged lines hidden (view full) --- 6190 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, 0); 6191 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, 0); 6192 rtnl_register(PF_UNSPEC, RTM_GETNETCONF, NULL, rtnl_dump_all, 0); 6193 6194 rtnl_register(PF_UNSPEC, RTM_NEWLINKPROP, rtnl_newlinkprop, NULL, 0); 6195 rtnl_register(PF_UNSPEC, RTM_DELLINKPROP, rtnl_dellinkprop, NULL, 0); 6196 6197 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, 0); |
6108 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 0); | 6198 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, 6199 RTNL_FLAG_BULK_DEL_SUPPORTED); |
6109 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0); 6110 6111 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0); 6112 rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0); 6113 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, 0); 6114 6115 rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump, 6116 0); 6117 rtnl_register(PF_UNSPEC, RTM_SETSTATS, rtnl_stats_set, NULL, 0); 6118} | 6200 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, rtnl_fdb_get, rtnl_fdb_dump, 0); 6201 6202 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, 0); 6203 rtnl_register(PF_BRIDGE, RTM_DELLINK, rtnl_bridge_dellink, NULL, 0); 6204 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, 0); 6205 6206 rtnl_register(PF_UNSPEC, RTM_GETSTATS, rtnl_stats_get, rtnl_stats_dump, 6207 0); 6208 rtnl_register(PF_UNSPEC, RTM_SETSTATS, rtnl_stats_set, NULL, 0); 6209} |