rtnetlink.c (d033a308d81ec83908760a15a841c2bd0d5e0ea3) rtnetlink.c (c07135633bee3f01a6454d15b6411f32cfbeb2fd)
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>

--- 114 unchanged lines hidden (view full) ---

123 if (protocol <= RTNL_FAMILY_MAX)
124 tab = rtnl_msg_handlers[protocol];
125 else
126 tab = NULL;
127
128 if (tab == NULL || tab[msgindex].doit == NULL)
129 tab = rtnl_msg_handlers[PF_UNSPEC];
130
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>

--- 114 unchanged lines hidden (view full) ---

123 if (protocol <= RTNL_FAMILY_MAX)
124 tab = rtnl_msg_handlers[protocol];
125 else
126 tab = NULL;
127
128 if (tab == NULL || tab[msgindex].doit == NULL)
129 tab = rtnl_msg_handlers[PF_UNSPEC];
130
131 return tab ? tab[msgindex].doit : NULL;
131 return tab[msgindex].doit;
132}
133
134static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
135{
136 struct rtnl_link *tab;
137
138 if (protocol <= RTNL_FAMILY_MAX)
139 tab = rtnl_msg_handlers[protocol];
140 else
141 tab = NULL;
142
143 if (tab == NULL || tab[msgindex].dumpit == NULL)
144 tab = rtnl_msg_handlers[PF_UNSPEC];
145
132}
133
134static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
135{
136 struct rtnl_link *tab;
137
138 if (protocol <= RTNL_FAMILY_MAX)
139 tab = rtnl_msg_handlers[protocol];
140 else
141 tab = NULL;
142
143 if (tab == NULL || tab[msgindex].dumpit == NULL)
144 tab = rtnl_msg_handlers[PF_UNSPEC];
145
146 return tab ? tab[msgindex].dumpit : NULL;
146 return tab[msgindex].dumpit;
147}
148
149static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex)
150{
151 struct rtnl_link *tab;
152
153 if (protocol <= RTNL_FAMILY_MAX)
154 tab = rtnl_msg_handlers[protocol];
155 else
156 tab = NULL;
157
158 if (tab == NULL || tab[msgindex].calcit == NULL)
159 tab = rtnl_msg_handlers[PF_UNSPEC];
160
147}
148
149static rtnl_calcit_func rtnl_get_calcit(int protocol, int msgindex)
150{
151 struct rtnl_link *tab;
152
153 if (protocol <= RTNL_FAMILY_MAX)
154 tab = rtnl_msg_handlers[protocol];
155 else
156 tab = NULL;
157
158 if (tab == NULL || tab[msgindex].calcit == NULL)
159 tab = rtnl_msg_handlers[PF_UNSPEC];
160
161 return tab ? tab[msgindex].calcit : NULL;
161 return tab[msgindex].calcit;
162}
163
164/**
165 * __rtnl_register - Register a rtnetlink message type
166 * @protocol: Protocol family or PF_UNSPEC
167 * @msgtype: rtnetlink message type
168 * @doit: Function pointer called for each request message
169 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message

--- 1141 unchanged lines hidden (view full) ---

1311 int err;
1312
1313 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) {
1314 struct net *net = rtnl_link_get_net(dev_net(dev), tb);
1315 if (IS_ERR(net)) {
1316 err = PTR_ERR(net);
1317 goto errout;
1318 }
162}
163
164/**
165 * __rtnl_register - Register a rtnetlink message type
166 * @protocol: Protocol family or PF_UNSPEC
167 * @msgtype: rtnetlink message type
168 * @doit: Function pointer called for each request message
169 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message

--- 1141 unchanged lines hidden (view full) ---

1311 int err;
1312
1313 if (tb[IFLA_NET_NS_PID] || tb[IFLA_NET_NS_FD]) {
1314 struct net *net = rtnl_link_get_net(dev_net(dev), tb);
1315 if (IS_ERR(net)) {
1316 err = PTR_ERR(net);
1317 goto errout;
1318 }
1319 if (!ns_capable(net->user_ns, CAP_NET_ADMIN)) {
1320 err = -EPERM;
1321 goto errout;
1322 }
1319 err = dev_change_net_namespace(dev, net, ifname);
1320 put_net(net);
1321 if (err)
1322 goto errout;
1323 modified = 1;
1324 }
1325
1326 if (tb[IFLA_MAP]) {

--- 306 unchanged lines hidden (view full) ---

1633 dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
1634 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
1635
1636 __dev_notify_flags(dev, old_flags);
1637 return 0;
1638}
1639EXPORT_SYMBOL(rtnl_configure_link);
1640
1323 err = dev_change_net_namespace(dev, net, ifname);
1324 put_net(net);
1325 if (err)
1326 goto errout;
1327 modified = 1;
1328 }
1329
1330 if (tb[IFLA_MAP]) {

--- 306 unchanged lines hidden (view full) ---

1637 dev->rtnl_link_state = RTNL_LINK_INITIALIZED;
1638 rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
1639
1640 __dev_notify_flags(dev, old_flags);
1641 return 0;
1642}
1643EXPORT_SYMBOL(rtnl_configure_link);
1644
1641struct net_device *rtnl_create_link(struct net *src_net, struct net *net,
1645struct net_device *rtnl_create_link(struct net *net,
1642 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[])
1643{
1644 int err;
1645 struct net_device *dev;
1646 unsigned int num_tx_queues = 1;
1647 unsigned int num_rx_queues = 1;
1648
1649 if (tb[IFLA_NUM_TX_QUEUES])

--- 181 unchanged lines hidden (view full) ---

1831
1832 if (!ifname[0])
1833 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
1834
1835 dest_net = rtnl_link_get_net(net, tb);
1836 if (IS_ERR(dest_net))
1837 return PTR_ERR(dest_net);
1838
1646 char *ifname, const struct rtnl_link_ops *ops, struct nlattr *tb[])
1647{
1648 int err;
1649 struct net_device *dev;
1650 unsigned int num_tx_queues = 1;
1651 unsigned int num_rx_queues = 1;
1652
1653 if (tb[IFLA_NUM_TX_QUEUES])

--- 181 unchanged lines hidden (view full) ---

1835
1836 if (!ifname[0])
1837 snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
1838
1839 dest_net = rtnl_link_get_net(net, tb);
1840 if (IS_ERR(dest_net))
1841 return PTR_ERR(dest_net);
1842
1839 dev = rtnl_create_link(net, dest_net, ifname, ops, tb);
1843 dev = rtnl_create_link(dest_net, ifname, ops, tb);
1840 if (IS_ERR(dev)) {
1841 err = PTR_ERR(dev);
1842 goto out;
1843 }
1844
1845 dev->ifindex = ifm->ifi_index;
1846
1847 if (ops->newlink)

--- 204 unchanged lines hidden (view full) ---

2052 struct net *net = sock_net(skb->sk);
2053 struct net_device *master = NULL;
2054 struct ndmsg *ndm;
2055 struct nlattr *tb[NDA_MAX+1];
2056 struct net_device *dev;
2057 u8 *addr;
2058 int err;
2059
1844 if (IS_ERR(dev)) {
1845 err = PTR_ERR(dev);
1846 goto out;
1847 }
1848
1849 dev->ifindex = ifm->ifi_index;
1850
1851 if (ops->newlink)

--- 204 unchanged lines hidden (view full) ---

2056 struct net *net = sock_net(skb->sk);
2057 struct net_device *master = NULL;
2058 struct ndmsg *ndm;
2059 struct nlattr *tb[NDA_MAX+1];
2060 struct net_device *dev;
2061 u8 *addr;
2062 int err;
2063
2064 if (!capable(CAP_NET_ADMIN))
2065 return -EPERM;
2066
2060 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
2061 if (err < 0)
2062 return err;
2063
2064 ndm = nlmsg_data(nlh);
2065 if (ndm->ndm_ifindex == 0) {
2066 pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ifindex\n");
2067 return -EINVAL;

--- 50 unchanged lines hidden (view full) ---

2118{
2119 struct net *net = sock_net(skb->sk);
2120 struct ndmsg *ndm;
2121 struct nlattr *llattr;
2122 struct net_device *dev;
2123 int err = -EINVAL;
2124 __u8 *addr;
2125
2067 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
2068 if (err < 0)
2069 return err;
2070
2071 ndm = nlmsg_data(nlh);
2072 if (ndm->ndm_ifindex == 0) {
2073 pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid ifindex\n");
2074 return -EINVAL;

--- 50 unchanged lines hidden (view full) ---

2125{
2126 struct net *net = sock_net(skb->sk);
2127 struct ndmsg *ndm;
2128 struct nlattr *llattr;
2129 struct net_device *dev;
2130 int err = -EINVAL;
2131 __u8 *addr;
2132
2133 if (!capable(CAP_NET_ADMIN))
2134 return -EPERM;
2135
2126 if (nlmsg_len(nlh) < sizeof(*ndm))
2127 return -EINVAL;
2128
2129 ndm = nlmsg_data(nlh);
2130 if (ndm->ndm_ifindex == 0) {
2131 pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ifindex\n");
2132 return -EINVAL;
2133 }

--- 114 unchanged lines hidden (view full) ---

2248 idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx);
2249 }
2250 rcu_read_unlock();
2251
2252 cb->args[0] = idx;
2253 return skb->len;
2254}
2255
2136 if (nlmsg_len(nlh) < sizeof(*ndm))
2137 return -EINVAL;
2138
2139 ndm = nlmsg_data(nlh);
2140 if (ndm->ndm_ifindex == 0) {
2141 pr_info("PF_BRIDGE: RTM_DELNEIGH with invalid ifindex\n");
2142 return -EINVAL;
2143 }

--- 114 unchanged lines hidden (view full) ---

2258 idx = dev->netdev_ops->ndo_fdb_dump(skb, cb, dev, idx);
2259 }
2260 rcu_read_unlock();
2261
2262 cb->args[0] = idx;
2263 return skb->len;
2264}
2265
2266int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
2267 struct net_device *dev, u16 mode)
2268{
2269 struct nlmsghdr *nlh;
2270 struct ifinfomsg *ifm;
2271 struct nlattr *br_afspec;
2272 u8 operstate = netif_running(dev) ? dev->operstate : IF_OPER_DOWN;
2273
2274 nlh = nlmsg_put(skb, pid, seq, RTM_NEWLINK, sizeof(*ifm), NLM_F_MULTI);
2275 if (nlh == NULL)
2276 return -EMSGSIZE;
2277
2278 ifm = nlmsg_data(nlh);
2279 ifm->ifi_family = AF_BRIDGE;
2280 ifm->__ifi_pad = 0;
2281 ifm->ifi_type = dev->type;
2282 ifm->ifi_index = dev->ifindex;
2283 ifm->ifi_flags = dev_get_flags(dev);
2284 ifm->ifi_change = 0;
2285
2286
2287 if (nla_put_string(skb, IFLA_IFNAME, dev->name) ||
2288 nla_put_u32(skb, IFLA_MTU, dev->mtu) ||
2289 nla_put_u8(skb, IFLA_OPERSTATE, operstate) ||
2290 (dev->master &&
2291 nla_put_u32(skb, IFLA_MASTER, dev->master->ifindex)) ||
2292 (dev->addr_len &&
2293 nla_put(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr)) ||
2294 (dev->ifindex != dev->iflink &&
2295 nla_put_u32(skb, IFLA_LINK, dev->iflink)))
2296 goto nla_put_failure;
2297
2298 br_afspec = nla_nest_start(skb, IFLA_AF_SPEC);
2299 if (!br_afspec)
2300 goto nla_put_failure;
2301
2302 if (nla_put_u16(skb, IFLA_BRIDGE_FLAGS, BRIDGE_FLAGS_SELF) ||
2303 nla_put_u16(skb, IFLA_BRIDGE_MODE, mode)) {
2304 nla_nest_cancel(skb, br_afspec);
2305 goto nla_put_failure;
2306 }
2307 nla_nest_end(skb, br_afspec);
2308
2309 return nlmsg_end(skb, nlh);
2310nla_put_failure:
2311 nlmsg_cancel(skb, nlh);
2312 return -EMSGSIZE;
2313}
2314EXPORT_SYMBOL(ndo_dflt_bridge_getlink);
2315
2316static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
2317{
2318 struct net *net = sock_net(skb->sk);
2319 struct net_device *dev;
2320 int idx = 0;
2321 u32 portid = NETLINK_CB(cb->skb).portid;
2322 u32 seq = cb->nlh->nlmsg_seq;
2323
2324 rcu_read_lock();
2325 for_each_netdev_rcu(net, dev) {
2326 const struct net_device_ops *ops = dev->netdev_ops;
2327 struct net_device *master = dev->master;
2328
2329 if (master && master->netdev_ops->ndo_bridge_getlink) {
2330 if (idx >= cb->args[0] &&
2331 master->netdev_ops->ndo_bridge_getlink(
2332 skb, portid, seq, dev) < 0)
2333 break;
2334 idx++;
2335 }
2336
2337 if (ops->ndo_bridge_getlink) {
2338 if (idx >= cb->args[0] &&
2339 ops->ndo_bridge_getlink(skb, portid, seq, dev) < 0)
2340 break;
2341 idx++;
2342 }
2343 }
2344 rcu_read_unlock();
2345 cb->args[0] = idx;
2346
2347 return skb->len;
2348}
2349
2350static inline size_t bridge_nlmsg_size(void)
2351{
2352 return NLMSG_ALIGN(sizeof(struct ifinfomsg))
2353 + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
2354 + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
2355 + nla_total_size(sizeof(u32)) /* IFLA_MASTER */
2356 + nla_total_size(sizeof(u32)) /* IFLA_MTU */
2357 + nla_total_size(sizeof(u32)) /* IFLA_LINK */
2358 + nla_total_size(sizeof(u32)) /* IFLA_OPERSTATE */
2359 + nla_total_size(sizeof(u8)) /* IFLA_PROTINFO */
2360 + nla_total_size(sizeof(struct nlattr)) /* IFLA_AF_SPEC */
2361 + nla_total_size(sizeof(u16)) /* IFLA_BRIDGE_FLAGS */
2362 + nla_total_size(sizeof(u16)); /* IFLA_BRIDGE_MODE */
2363}
2364
2365static int rtnl_bridge_notify(struct net_device *dev, u16 flags)
2366{
2367 struct net *net = dev_net(dev);
2368 struct net_device *master = dev->master;
2369 struct sk_buff *skb;
2370 int err = -EOPNOTSUPP;
2371
2372 skb = nlmsg_new(bridge_nlmsg_size(), GFP_ATOMIC);
2373 if (!skb) {
2374 err = -ENOMEM;
2375 goto errout;
2376 }
2377
2378 if ((!flags || (flags & BRIDGE_FLAGS_MASTER)) &&
2379 master && master->netdev_ops->ndo_bridge_getlink) {
2380 err = master->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev);
2381 if (err < 0)
2382 goto errout;
2383 }
2384
2385 if ((flags & BRIDGE_FLAGS_SELF) &&
2386 dev->netdev_ops->ndo_bridge_getlink) {
2387 err = dev->netdev_ops->ndo_bridge_getlink(skb, 0, 0, dev);
2388 if (err < 0)
2389 goto errout;
2390 }
2391
2392 rtnl_notify(skb, net, 0, RTNLGRP_LINK, NULL, GFP_ATOMIC);
2393 return 0;
2394errout:
2395 WARN_ON(err == -EMSGSIZE);
2396 kfree_skb(skb);
2397 rtnl_set_sk_err(net, RTNLGRP_LINK, err);
2398 return err;
2399}
2400
2401static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
2402 void *arg)
2403{
2404 struct net *net = sock_net(skb->sk);
2405 struct ifinfomsg *ifm;
2406 struct net_device *dev;
2407 struct nlattr *br_spec, *attr = NULL;
2408 int rem, err = -EOPNOTSUPP;
2409 u16 oflags, flags = 0;
2410 bool have_flags = false;
2411
2412 if (nlmsg_len(nlh) < sizeof(*ifm))
2413 return -EINVAL;
2414
2415 ifm = nlmsg_data(nlh);
2416 if (ifm->ifi_family != AF_BRIDGE)
2417 return -EPFNOSUPPORT;
2418
2419 dev = __dev_get_by_index(net, ifm->ifi_index);
2420 if (!dev) {
2421 pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n");
2422 return -ENODEV;
2423 }
2424
2425 br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
2426 if (br_spec) {
2427 nla_for_each_nested(attr, br_spec, rem) {
2428 if (nla_type(attr) == IFLA_BRIDGE_FLAGS) {
2429 have_flags = true;
2430 flags = nla_get_u16(attr);
2431 break;
2432 }
2433 }
2434 }
2435
2436 oflags = flags;
2437
2438 if (!flags || (flags & BRIDGE_FLAGS_MASTER)) {
2439 if (!dev->master ||
2440 !dev->master->netdev_ops->ndo_bridge_setlink) {
2441 err = -EOPNOTSUPP;
2442 goto out;
2443 }
2444
2445 err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh);
2446 if (err)
2447 goto out;
2448
2449 flags &= ~BRIDGE_FLAGS_MASTER;
2450 }
2451
2452 if ((flags & BRIDGE_FLAGS_SELF)) {
2453 if (!dev->netdev_ops->ndo_bridge_setlink)
2454 err = -EOPNOTSUPP;
2455 else
2456 err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
2457
2458 if (!err)
2459 flags &= ~BRIDGE_FLAGS_SELF;
2460 }
2461
2462 if (have_flags)
2463 memcpy(nla_data(attr), &flags, sizeof(flags));
2464 /* Generate event to notify upper layer of bridge change */
2465 if (!err)
2466 err = rtnl_bridge_notify(dev, oflags);
2467out:
2468 return err;
2469}
2470
2256/* Protected by RTNL sempahore. */
2257static struct rtattr **rta_buf;
2258static int rtattr_max;
2259
2260/* Process one rtnetlink message. */
2261
2262static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
2263{

--- 14 unchanged lines hidden (view full) ---

2278 /* All the messages must have at least 1 byte length */
2279 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg)))
2280 return 0;
2281
2282 family = ((struct rtgenmsg *)NLMSG_DATA(nlh))->rtgen_family;
2283 sz_idx = type>>2;
2284 kind = type&3;
2285
2471/* Protected by RTNL sempahore. */
2472static struct rtattr **rta_buf;
2473static int rtattr_max;
2474
2475/* Process one rtnetlink message. */
2476
2477static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
2478{

--- 14 unchanged lines hidden (view full) ---

2493 /* All the messages must have at least 1 byte length */
2494 if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg)))
2495 return 0;
2496
2497 family = ((struct rtgenmsg *)NLMSG_DATA(nlh))->rtgen_family;
2498 sz_idx = type>>2;
2499 kind = type&3;
2500
2286 if (kind != 2 && !capable(CAP_NET_ADMIN))
2501 if (kind != 2 && !ns_capable(net->user_ns, CAP_NET_ADMIN))
2287 return -EPERM;
2288
2289 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
2290 struct sock *rtnl;
2291 rtnl_dumpit_func dumpit;
2292 rtnl_calcit_func calcit;
2293 u16 min_dump_alloc = 0;
2294

--- 134 unchanged lines hidden (view full) ---

2429 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, NULL);
2430
2431 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL);
2432 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL);
2433
2434 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL);
2435 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL);
2436 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL);
2502 return -EPERM;
2503
2504 if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
2505 struct sock *rtnl;
2506 rtnl_dumpit_func dumpit;
2507 rtnl_calcit_func calcit;
2508 u16 min_dump_alloc = 0;
2509

--- 134 unchanged lines hidden (view full) ---

2644 rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL, NULL);
2645
2646 rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all, NULL);
2647 rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all, NULL);
2648
2649 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL);
2650 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL);
2651 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL);
2652
2653 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL);
2654 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL);
2437}
2438
2655}
2656