rtnetlink.c (e5a55a898720096f43bc24938f8875c0a1b34cd7) | rtnetlink.c (2469ffd723f76ac2d3ce3d4f31ee31ee0a06cd38) |
---|---|
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> --- 2281 unchanged lines hidden (view full) --- 2290 } 2291 } 2292 rcu_read_unlock(); 2293 cb->args[0] = idx; 2294 2295 return skb->len; 2296} 2297 | 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> --- 2281 unchanged lines hidden (view full) --- 2290 } 2291 } 2292 rcu_read_unlock(); 2293 cb->args[0] = idx; 2294 2295 return skb->len; 2296} 2297 |
2298static inline size_t bridge_nlmsg_size(void) 2299{ 2300 return NLMSG_ALIGN(sizeof(struct ifinfomsg)) 2301 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */ 2302 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */ 2303 + nla_total_size(sizeof(u32)) /* IFLA_MASTER */ 2304 + nla_total_size(sizeof(u32)) /* IFLA_MTU */ 2305 + nla_total_size(sizeof(u32)) /* IFLA_LINK */ 2306 + nla_total_size(sizeof(u32)) /* IFLA_OPERSTATE */ 2307 + nla_total_size(sizeof(u8)) /* IFLA_PROTINFO */ 2308 + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */ 2309 + nla_total_size(sizeof(u16)) /* IFLA_BRIDGE_FLAGS */ 2310 + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */ 2311} 2312 2313static int rtnl_bridge_notify(struct net_device *dev, u16 flags) 2314{ 2315 struct net *net = dev_net(dev); 2316 struct net_device *master = dev->master; 2317 struct sk_buff *skb; 2318 int err = -EOPNOTSUPP; 2319 2320 skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC); 2321 if (!skb) { 2322 err = -ENOMEM; 2323 goto errout; 2324 } 2325 2326 if (!flags && master && master->netdev_ops->ndo_bridge_getlink) 2327 err = master->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev); 2328 else if (dev->netdev_ops->ndo_bridge_getlink) 2329 err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev); 2330 2331 if (err < 0) 2332 goto errout; 2333 2334 rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC); 2335 return 0; 2336errout: 2337 WARN_ON(err == -EMSGSIZE); 2338 kfree_skb(skb); 2339 rtnl_set_sk_err(net, RTNLGRP_LINK, err); 2340 return err; 2341} 2342 |
|
2298static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, 2299 void *arg) 2300{ 2301 struct net *net = sock_net(skb->sk); 2302 struct ifinfomsg *ifm; 2303 struct net_device *dev; | 2343static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, 2344 void *arg) 2345{ 2346 struct net *net = sock_net(skb->sk); 2347 struct ifinfomsg *ifm; 2348 struct net_device *dev; |
2304 int err = -EINVAL; | 2349 struct nlattr *br_spec, *attr = NULL; 2350 int rem, err = -EOPNOTSUPP; 2351 u16 flags = 0; |
2305 2306 if (nlmsg_len(nlh) < sizeof(*ifm)) 2307 return -EINVAL; 2308 2309 ifm = nlmsg_data(nlh); 2310 if (ifm->ifi_family != AF_BRIDGE) 2311 return -EPFNOSUPPORT; 2312 2313 dev = __dev_get_by_index(net, ifm->ifi_index); 2314 if (!dev) { 2315 pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n"); 2316 return -ENODEV; 2317 } 2318 | 2352 2353 if (nlmsg_len(nlh) < sizeof(*ifm)) 2354 return -EINVAL; 2355 2356 ifm = nlmsg_data(nlh); 2357 if (ifm->ifi_family != AF_BRIDGE) 2358 return -EPFNOSUPPORT; 2359 2360 dev = __dev_get_by_index(net, ifm->ifi_index); 2361 if (!dev) { 2362 pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n"); 2363 return -ENODEV; 2364 } 2365 |
2319 if (dev->master && dev->master->netdev_ops->ndo_bridge_setlink) { | 2366 br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC); 2367 if (br_spec) { 2368 nla_for_each_nested(attr, br_spec, rem) { 2369 if (nla_type(attr) == IFLA_BRIDGE_FLAGS) { 2370 flags = nla_get_u16(attr); 2371 break; 2372 } 2373 } 2374 } 2375 2376 if (!flags || (flags & BRIDGE_FLAGS_MASTER)) { 2377 if (!dev->master || 2378 !dev->master->netdev_ops->ndo_bridge_setlink) { 2379 err = -EOPNOTSUPP; 2380 goto out; 2381 } 2382 |
2320 err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh); 2321 if (err) 2322 goto out; | 2383 err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh); 2384 if (err) 2385 goto out; |
2386 2387 flags &= ~BRIDGE_FLAGS_MASTER; |
|
2323 } 2324 | 2388 } 2389 |
2325 if (dev->netdev_ops->ndo_bridge_setlink) 2326 err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh); | 2390 if ((flags & BRIDGE_FLAGS_SELF)) { 2391 if (!dev->netdev_ops->ndo_bridge_setlink) 2392 err = -EOPNOTSUPP; 2393 else 2394 err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh); |
2327 | 2395 |
2396 if (!err) 2397 flags &= ~BRIDGE_FLAGS_SELF; 2398 } 2399 2400 if (attr && nla_type(attr) == IFLA_BRIDGE_FLAGS) 2401 memcpy(nla_data(attr), &flags, sizeof(flags)); 2402 /* Generate event to notify upper layer of bridge change */ 2403 if (!err) 2404 err = rtnl_bridge_notify(dev, flags); |
|
2328out: 2329 return err; 2330} 2331 2332/* Protected by RTNL sempahore. */ 2333static struct rtattr **rta_buf; 2334static int rtattr_max; 2335 --- 182 unchanged lines hidden --- | 2405out: 2406 return err; 2407} 2408 2409/* Protected by RTNL sempahore. */ 2410static struct rtattr **rta_buf; 2411static int rtattr_max; 2412 --- 182 unchanged lines hidden --- |