OpenCores
URL https://opencores.org/ocsvn/or1k_soc_on_altera_embedded_dev_kit/or1k_soc_on_altera_embedded_dev_kit/trunk

Subversion Repositories or1k_soc_on_altera_embedded_dev_kit

[/] [or1k_soc_on_altera_embedded_dev_kit/] [trunk/] [linux-2.6/] [linux-2.6.24/] [net/] [core/] [rtnetlink.c] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 3 xianfeng
/*
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>
9
 *
10
 *              This program is free software; you can redistribute it and/or
11
 *              modify it under the terms of the GNU General Public License
12
 *              as published by the Free Software Foundation; either version
13
 *              2 of the License, or (at your option) any later version.
14
 *
15
 *      Fixes:
16
 *      Vitaly E. Lavrov                RTA_OK arithmetics was wrong.
17
 */
18
 
19
#include <linux/errno.h>
20
#include <linux/module.h>
21
#include <linux/types.h>
22
#include <linux/socket.h>
23
#include <linux/kernel.h>
24
#include <linux/timer.h>
25
#include <linux/string.h>
26
#include <linux/sockios.h>
27
#include <linux/net.h>
28
#include <linux/fcntl.h>
29
#include <linux/mm.h>
30
#include <linux/slab.h>
31
#include <linux/interrupt.h>
32
#include <linux/capability.h>
33
#include <linux/skbuff.h>
34
#include <linux/init.h>
35
#include <linux/security.h>
36
#include <linux/mutex.h>
37
#include <linux/if_addr.h>
38
#include <linux/nsproxy.h>
39
 
40
#include <asm/uaccess.h>
41
#include <asm/system.h>
42
#include <asm/string.h>
43
 
44
#include <linux/inet.h>
45
#include <linux/netdevice.h>
46
#include <net/ip.h>
47
#include <net/protocol.h>
48
#include <net/arp.h>
49
#include <net/route.h>
50
#include <net/udp.h>
51
#include <net/sock.h>
52
#include <net/pkt_sched.h>
53
#include <net/fib_rules.h>
54
#include <net/rtnetlink.h>
55
 
56
struct rtnl_link
57
{
58
        rtnl_doit_func          doit;
59
        rtnl_dumpit_func        dumpit;
60
};
61
 
62
static DEFINE_MUTEX(rtnl_mutex);
63
static struct sock *rtnl;
64
 
65
void rtnl_lock(void)
66
{
67
        mutex_lock(&rtnl_mutex);
68
}
69
 
70
void __rtnl_unlock(void)
71
{
72
        mutex_unlock(&rtnl_mutex);
73
}
74
 
75
void rtnl_unlock(void)
76
{
77
        mutex_unlock(&rtnl_mutex);
78
        netdev_run_todo();
79
}
80
 
81
int rtnl_trylock(void)
82
{
83
        return mutex_trylock(&rtnl_mutex);
84
}
85
 
86
int rtattr_parse(struct rtattr *tb[], int maxattr, struct rtattr *rta, int len)
87
{
88
        memset(tb, 0, sizeof(struct rtattr*)*maxattr);
89
 
90
        while (RTA_OK(rta, len)) {
91
                unsigned flavor = rta->rta_type;
92
                if (flavor && flavor <= maxattr)
93
                        tb[flavor-1] = rta;
94
                rta = RTA_NEXT(rta, len);
95
        }
96
        return 0;
97
}
98
 
99
int __rtattr_parse_nested_compat(struct rtattr *tb[], int maxattr,
100
                                 struct rtattr *rta, int len)
101
{
102
        if (RTA_PAYLOAD(rta) < len)
103
                return -1;
104
        if (RTA_PAYLOAD(rta) >= RTA_ALIGN(len) + sizeof(struct rtattr)) {
105
                rta = RTA_DATA(rta) + RTA_ALIGN(len);
106
                return rtattr_parse_nested(tb, maxattr, rta);
107
        }
108
        memset(tb, 0, sizeof(struct rtattr *) * maxattr);
109
        return 0;
110
}
111
 
112
static struct rtnl_link *rtnl_msg_handlers[NPROTO];
113
 
114
static inline int rtm_msgindex(int msgtype)
115
{
116
        int msgindex = msgtype - RTM_BASE;
117
 
118
        /*
119
         * msgindex < 0 implies someone tried to register a netlink
120
         * control code. msgindex >= RTM_NR_MSGTYPES may indicate that
121
         * the message type has not been added to linux/rtnetlink.h
122
         */
123
        BUG_ON(msgindex < 0 || msgindex >= RTM_NR_MSGTYPES);
124
 
125
        return msgindex;
126
}
127
 
128
static rtnl_doit_func rtnl_get_doit(int protocol, int msgindex)
129
{
130
        struct rtnl_link *tab;
131
 
132
        tab = rtnl_msg_handlers[protocol];
133
        if (tab == NULL || tab[msgindex].doit == NULL)
134
                tab = rtnl_msg_handlers[PF_UNSPEC];
135
 
136
        return tab ? tab[msgindex].doit : NULL;
137
}
138
 
139
static rtnl_dumpit_func rtnl_get_dumpit(int protocol, int msgindex)
140
{
141
        struct rtnl_link *tab;
142
 
143
        tab = rtnl_msg_handlers[protocol];
144
        if (tab == NULL || tab[msgindex].dumpit == NULL)
145
                tab = rtnl_msg_handlers[PF_UNSPEC];
146
 
147
        return tab ? tab[msgindex].dumpit : NULL;
148
}
149
 
150
/**
151
 * __rtnl_register - Register a rtnetlink message type
152
 * @protocol: Protocol family or PF_UNSPEC
153
 * @msgtype: rtnetlink message type
154
 * @doit: Function pointer called for each request message
155
 * @dumpit: Function pointer called for each dump request (NLM_F_DUMP) message
156
 *
157
 * Registers the specified function pointers (at least one of them has
158
 * to be non-NULL) to be called whenever a request message for the
159
 * specified protocol family and message type is received.
160
 *
161
 * The special protocol family PF_UNSPEC may be used to define fallback
162
 * function pointers for the case when no entry for the specific protocol
163
 * family exists.
164
 *
165
 * Returns 0 on success or a negative error code.
166
 */
167
int __rtnl_register(int protocol, int msgtype,
168
                    rtnl_doit_func doit, rtnl_dumpit_func dumpit)
169
{
170
        struct rtnl_link *tab;
171
        int msgindex;
172
 
173
        BUG_ON(protocol < 0 || protocol >= NPROTO);
174
        msgindex = rtm_msgindex(msgtype);
175
 
176
        tab = rtnl_msg_handlers[protocol];
177
        if (tab == NULL) {
178
                tab = kcalloc(RTM_NR_MSGTYPES, sizeof(*tab), GFP_KERNEL);
179
                if (tab == NULL)
180
                        return -ENOBUFS;
181
 
182
                rtnl_msg_handlers[protocol] = tab;
183
        }
184
 
185
        if (doit)
186
                tab[msgindex].doit = doit;
187
 
188
        if (dumpit)
189
                tab[msgindex].dumpit = dumpit;
190
 
191
        return 0;
192
}
193
 
194
EXPORT_SYMBOL_GPL(__rtnl_register);
195
 
196
/**
197
 * rtnl_register - Register a rtnetlink message type
198
 *
199
 * Identical to __rtnl_register() but panics on failure. This is useful
200
 * as failure of this function is very unlikely, it can only happen due
201
 * to lack of memory when allocating the chain to store all message
202
 * handlers for a protocol. Meant for use in init functions where lack
203
 * of memory implies no sense in continueing.
204
 */
205
void rtnl_register(int protocol, int msgtype,
206
                   rtnl_doit_func doit, rtnl_dumpit_func dumpit)
207
{
208
        if (__rtnl_register(protocol, msgtype, doit, dumpit) < 0)
209
                panic("Unable to register rtnetlink message handler, "
210
                      "protocol = %d, message type = %d\n",
211
                      protocol, msgtype);
212
}
213
 
214
EXPORT_SYMBOL_GPL(rtnl_register);
215
 
216
/**
217
 * rtnl_unregister - Unregister a rtnetlink message type
218
 * @protocol: Protocol family or PF_UNSPEC
219
 * @msgtype: rtnetlink message type
220
 *
221
 * Returns 0 on success or a negative error code.
222
 */
223
int rtnl_unregister(int protocol, int msgtype)
224
{
225
        int msgindex;
226
 
227
        BUG_ON(protocol < 0 || protocol >= NPROTO);
228
        msgindex = rtm_msgindex(msgtype);
229
 
230
        if (rtnl_msg_handlers[protocol] == NULL)
231
                return -ENOENT;
232
 
233
        rtnl_msg_handlers[protocol][msgindex].doit = NULL;
234
        rtnl_msg_handlers[protocol][msgindex].dumpit = NULL;
235
 
236
        return 0;
237
}
238
 
239
EXPORT_SYMBOL_GPL(rtnl_unregister);
240
 
241
/**
242
 * rtnl_unregister_all - Unregister all rtnetlink message type of a protocol
243
 * @protocol : Protocol family or PF_UNSPEC
244
 *
245
 * Identical to calling rtnl_unregster() for all registered message types
246
 * of a certain protocol family.
247
 */
248
void rtnl_unregister_all(int protocol)
249
{
250
        BUG_ON(protocol < 0 || protocol >= NPROTO);
251
 
252
        kfree(rtnl_msg_handlers[protocol]);
253
        rtnl_msg_handlers[protocol] = NULL;
254
}
255
 
256
EXPORT_SYMBOL_GPL(rtnl_unregister_all);
257
 
258
static LIST_HEAD(link_ops);
259
 
260
/**
261
 * __rtnl_link_register - Register rtnl_link_ops with rtnetlink.
262
 * @ops: struct rtnl_link_ops * to register
263
 *
264
 * The caller must hold the rtnl_mutex. This function should be used
265
 * by drivers that create devices during module initialization. It
266
 * must be called before registering the devices.
267
 *
268
 * Returns 0 on success or a negative error code.
269
 */
270
int __rtnl_link_register(struct rtnl_link_ops *ops)
271
{
272
        if (!ops->dellink)
273
                ops->dellink = unregister_netdevice;
274
 
275
        list_add_tail(&ops->list, &link_ops);
276
        return 0;
277
}
278
 
279
EXPORT_SYMBOL_GPL(__rtnl_link_register);
280
 
281
/**
282
 * rtnl_link_register - Register rtnl_link_ops with rtnetlink.
283
 * @ops: struct rtnl_link_ops * to register
284
 *
285
 * Returns 0 on success or a negative error code.
286
 */
287
int rtnl_link_register(struct rtnl_link_ops *ops)
288
{
289
        int err;
290
 
291
        rtnl_lock();
292
        err = __rtnl_link_register(ops);
293
        rtnl_unlock();
294
        return err;
295
}
296
 
297
EXPORT_SYMBOL_GPL(rtnl_link_register);
298
 
299
/**
300
 * __rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
301
 * @ops: struct rtnl_link_ops * to unregister
302
 *
303
 * The caller must hold the rtnl_mutex.
304
 */
305
void __rtnl_link_unregister(struct rtnl_link_ops *ops)
306
{
307
        struct net_device *dev, *n;
308
        struct net *net;
309
 
310
        for_each_net(net) {
311
restart:
312
                for_each_netdev_safe(net, dev, n) {
313
                        if (dev->rtnl_link_ops == ops) {
314
                                ops->dellink(dev);
315
                                goto restart;
316
                        }
317
                }
318
        }
319
        list_del(&ops->list);
320
}
321
 
322
EXPORT_SYMBOL_GPL(__rtnl_link_unregister);
323
 
324
/**
325
 * rtnl_link_unregister - Unregister rtnl_link_ops from rtnetlink.
326
 * @ops: struct rtnl_link_ops * to unregister
327
 */
328
void rtnl_link_unregister(struct rtnl_link_ops *ops)
329
{
330
        rtnl_lock();
331
        __rtnl_link_unregister(ops);
332
        rtnl_unlock();
333
}
334
 
335
EXPORT_SYMBOL_GPL(rtnl_link_unregister);
336
 
337
static const struct rtnl_link_ops *rtnl_link_ops_get(const char *kind)
338
{
339
        const struct rtnl_link_ops *ops;
340
 
341
        list_for_each_entry(ops, &link_ops, list) {
342
                if (!strcmp(ops->kind, kind))
343
                        return ops;
344
        }
345
        return NULL;
346
}
347
 
348
static size_t rtnl_link_get_size(const struct net_device *dev)
349
{
350
        const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
351
        size_t size;
352
 
353
        if (!ops)
354
                return 0;
355
 
356
        size = nlmsg_total_size(sizeof(struct nlattr)) + /* IFLA_LINKINFO */
357
               nlmsg_total_size(strlen(ops->kind) + 1);  /* IFLA_INFO_KIND */
358
 
359
        if (ops->get_size)
360
                /* IFLA_INFO_DATA + nested data */
361
                size += nlmsg_total_size(sizeof(struct nlattr)) +
362
                        ops->get_size(dev);
363
 
364
        if (ops->get_xstats_size)
365
                size += ops->get_xstats_size(dev);      /* IFLA_INFO_XSTATS */
366
 
367
        return size;
368
}
369
 
370
static int rtnl_link_fill(struct sk_buff *skb, const struct net_device *dev)
371
{
372
        const struct rtnl_link_ops *ops = dev->rtnl_link_ops;
373
        struct nlattr *linkinfo, *data;
374
        int err = -EMSGSIZE;
375
 
376
        linkinfo = nla_nest_start(skb, IFLA_LINKINFO);
377
        if (linkinfo == NULL)
378
                goto out;
379
 
380
        if (nla_put_string(skb, IFLA_INFO_KIND, ops->kind) < 0)
381
                goto err_cancel_link;
382
        if (ops->fill_xstats) {
383
                err = ops->fill_xstats(skb, dev);
384
                if (err < 0)
385
                        goto err_cancel_link;
386
        }
387
        if (ops->fill_info) {
388
                data = nla_nest_start(skb, IFLA_INFO_DATA);
389
                if (data == NULL)
390
                        goto err_cancel_link;
391
                err = ops->fill_info(skb, dev);
392
                if (err < 0)
393
                        goto err_cancel_data;
394
                nla_nest_end(skb, data);
395
        }
396
 
397
        nla_nest_end(skb, linkinfo);
398
        return 0;
399
 
400
err_cancel_data:
401
        nla_nest_cancel(skb, data);
402
err_cancel_link:
403
        nla_nest_cancel(skb, linkinfo);
404
out:
405
        return err;
406
}
407
 
408
static const int rtm_min[RTM_NR_FAMILIES] =
409
{
410
        [RTM_FAM(RTM_NEWLINK)]      = NLMSG_LENGTH(sizeof(struct ifinfomsg)),
411
        [RTM_FAM(RTM_NEWADDR)]      = NLMSG_LENGTH(sizeof(struct ifaddrmsg)),
412
        [RTM_FAM(RTM_NEWROUTE)]     = NLMSG_LENGTH(sizeof(struct rtmsg)),
413
        [RTM_FAM(RTM_NEWRULE)]      = NLMSG_LENGTH(sizeof(struct fib_rule_hdr)),
414
        [RTM_FAM(RTM_NEWQDISC)]     = NLMSG_LENGTH(sizeof(struct tcmsg)),
415
        [RTM_FAM(RTM_NEWTCLASS)]    = NLMSG_LENGTH(sizeof(struct tcmsg)),
416
        [RTM_FAM(RTM_NEWTFILTER)]   = NLMSG_LENGTH(sizeof(struct tcmsg)),
417
        [RTM_FAM(RTM_NEWACTION)]    = NLMSG_LENGTH(sizeof(struct tcamsg)),
418
        [RTM_FAM(RTM_GETMULTICAST)] = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
419
        [RTM_FAM(RTM_GETANYCAST)]   = NLMSG_LENGTH(sizeof(struct rtgenmsg)),
420
};
421
 
422
static const int rta_max[RTM_NR_FAMILIES] =
423
{
424
        [RTM_FAM(RTM_NEWLINK)]      = IFLA_MAX,
425
        [RTM_FAM(RTM_NEWADDR)]      = IFA_MAX,
426
        [RTM_FAM(RTM_NEWROUTE)]     = RTA_MAX,
427
        [RTM_FAM(RTM_NEWRULE)]      = FRA_MAX,
428
        [RTM_FAM(RTM_NEWQDISC)]     = TCA_MAX,
429
        [RTM_FAM(RTM_NEWTCLASS)]    = TCA_MAX,
430
        [RTM_FAM(RTM_NEWTFILTER)]   = TCA_MAX,
431
        [RTM_FAM(RTM_NEWACTION)]    = TCAA_MAX,
432
};
433
 
434
void __rta_fill(struct sk_buff *skb, int attrtype, int attrlen, const void *data)
435
{
436
        struct rtattr *rta;
437
        int size = RTA_LENGTH(attrlen);
438
 
439
        rta = (struct rtattr*)skb_put(skb, RTA_ALIGN(size));
440
        rta->rta_type = attrtype;
441
        rta->rta_len = size;
442
        memcpy(RTA_DATA(rta), data, attrlen);
443
        memset(RTA_DATA(rta) + attrlen, 0, RTA_ALIGN(size) - size);
444
}
445
 
446
size_t rtattr_strlcpy(char *dest, const struct rtattr *rta, size_t size)
447
{
448
        size_t ret = RTA_PAYLOAD(rta);
449
        char *src = RTA_DATA(rta);
450
 
451
        if (ret > 0 && src[ret - 1] == '\0')
452
                ret--;
453
        if (size > 0) {
454
                size_t len = (ret >= size) ? size - 1 : ret;
455
                memset(dest, 0, size);
456
                memcpy(dest, src, len);
457
        }
458
        return ret;
459
}
460
 
461
int rtnetlink_send(struct sk_buff *skb, u32 pid, unsigned group, int echo)
462
{
463
        int err = 0;
464
 
465
        NETLINK_CB(skb).dst_group = group;
466
        if (echo)
467
                atomic_inc(&skb->users);
468
        netlink_broadcast(rtnl, skb, pid, group, GFP_KERNEL);
469
        if (echo)
470
                err = netlink_unicast(rtnl, skb, pid, MSG_DONTWAIT);
471
        return err;
472
}
473
 
474
int rtnl_unicast(struct sk_buff *skb, u32 pid)
475
{
476
        return nlmsg_unicast(rtnl, skb, pid);
477
}
478
 
479
int rtnl_notify(struct sk_buff *skb, u32 pid, u32 group,
480
                struct nlmsghdr *nlh, gfp_t flags)
481
{
482
        int report = 0;
483
 
484
        if (nlh)
485
                report = nlmsg_report(nlh);
486
 
487
        return nlmsg_notify(rtnl, skb, pid, group, report, flags);
488
}
489
 
490
void rtnl_set_sk_err(u32 group, int error)
491
{
492
        netlink_set_err(rtnl, 0, group, error);
493
}
494
 
495
int rtnetlink_put_metrics(struct sk_buff *skb, u32 *metrics)
496
{
497
        struct nlattr *mx;
498
        int i, valid = 0;
499
 
500
        mx = nla_nest_start(skb, RTA_METRICS);
501
        if (mx == NULL)
502
                return -ENOBUFS;
503
 
504
        for (i = 0; i < RTAX_MAX; i++) {
505
                if (metrics[i]) {
506
                        valid++;
507
                        NLA_PUT_U32(skb, i+1, metrics[i]);
508
                }
509
        }
510
 
511
        if (!valid) {
512
                nla_nest_cancel(skb, mx);
513
                return 0;
514
        }
515
 
516
        return nla_nest_end(skb, mx);
517
 
518
nla_put_failure:
519
        return nla_nest_cancel(skb, mx);
520
}
521
 
522
int rtnl_put_cacheinfo(struct sk_buff *skb, struct dst_entry *dst, u32 id,
523
                       u32 ts, u32 tsage, long expires, u32 error)
524
{
525
        struct rta_cacheinfo ci = {
526
                .rta_lastuse = jiffies_to_clock_t(jiffies - dst->lastuse),
527
                .rta_used = dst->__use,
528
                .rta_clntref = atomic_read(&(dst->__refcnt)),
529
                .rta_error = error,
530
                .rta_id =  id,
531
                .rta_ts = ts,
532
                .rta_tsage = tsage,
533
        };
534
 
535
        if (expires)
536
                ci.rta_expires = jiffies_to_clock_t(expires);
537
 
538
        return nla_put(skb, RTA_CACHEINFO, sizeof(ci), &ci);
539
}
540
 
541
EXPORT_SYMBOL_GPL(rtnl_put_cacheinfo);
542
 
543
static void set_operstate(struct net_device *dev, unsigned char transition)
544
{
545
        unsigned char operstate = dev->operstate;
546
 
547
        switch(transition) {
548
        case IF_OPER_UP:
549
                if ((operstate == IF_OPER_DORMANT ||
550
                     operstate == IF_OPER_UNKNOWN) &&
551
                    !netif_dormant(dev))
552
                        operstate = IF_OPER_UP;
553
                break;
554
 
555
        case IF_OPER_DORMANT:
556
                if (operstate == IF_OPER_UP ||
557
                    operstate == IF_OPER_UNKNOWN)
558
                        operstate = IF_OPER_DORMANT;
559
                break;
560
        }
561
 
562
        if (dev->operstate != operstate) {
563
                write_lock_bh(&dev_base_lock);
564
                dev->operstate = operstate;
565
                write_unlock_bh(&dev_base_lock);
566
                netdev_state_change(dev);
567
        }
568
}
569
 
570
static void copy_rtnl_link_stats(struct rtnl_link_stats *a,
571
                                 struct net_device_stats *b)
572
{
573
        a->rx_packets = b->rx_packets;
574
        a->tx_packets = b->tx_packets;
575
        a->rx_bytes = b->rx_bytes;
576
        a->tx_bytes = b->tx_bytes;
577
        a->rx_errors = b->rx_errors;
578
        a->tx_errors = b->tx_errors;
579
        a->rx_dropped = b->rx_dropped;
580
        a->tx_dropped = b->tx_dropped;
581
 
582
        a->multicast = b->multicast;
583
        a->collisions = b->collisions;
584
 
585
        a->rx_length_errors = b->rx_length_errors;
586
        a->rx_over_errors = b->rx_over_errors;
587
        a->rx_crc_errors = b->rx_crc_errors;
588
        a->rx_frame_errors = b->rx_frame_errors;
589
        a->rx_fifo_errors = b->rx_fifo_errors;
590
        a->rx_missed_errors = b->rx_missed_errors;
591
 
592
        a->tx_aborted_errors = b->tx_aborted_errors;
593
        a->tx_carrier_errors = b->tx_carrier_errors;
594
        a->tx_fifo_errors = b->tx_fifo_errors;
595
        a->tx_heartbeat_errors = b->tx_heartbeat_errors;
596
        a->tx_window_errors = b->tx_window_errors;
597
 
598
        a->rx_compressed = b->rx_compressed;
599
        a->tx_compressed = b->tx_compressed;
600
};
601
 
602
static inline size_t if_nlmsg_size(const struct net_device *dev)
603
{
604
        return NLMSG_ALIGN(sizeof(struct ifinfomsg))
605
               + nla_total_size(IFNAMSIZ) /* IFLA_IFNAME */
606
               + nla_total_size(IFNAMSIZ) /* IFLA_QDISC */
607
               + nla_total_size(sizeof(struct rtnl_link_ifmap))
608
               + nla_total_size(sizeof(struct rtnl_link_stats))
609
               + nla_total_size(MAX_ADDR_LEN) /* IFLA_ADDRESS */
610
               + nla_total_size(MAX_ADDR_LEN) /* IFLA_BROADCAST */
611
               + nla_total_size(4) /* IFLA_TXQLEN */
612
               + nla_total_size(4) /* IFLA_WEIGHT */
613
               + nla_total_size(4) /* IFLA_MTU */
614
               + nla_total_size(4) /* IFLA_LINK */
615
               + nla_total_size(4) /* IFLA_MASTER */
616
               + nla_total_size(1) /* IFLA_OPERSTATE */
617
               + nla_total_size(1) /* IFLA_LINKMODE */
618
               + rtnl_link_get_size(dev); /* IFLA_LINKINFO */
619
}
620
 
621
static int rtnl_fill_ifinfo(struct sk_buff *skb, struct net_device *dev,
622
                            int type, u32 pid, u32 seq, u32 change,
623
                            unsigned int flags)
624
{
625
        struct ifinfomsg *ifm;
626
        struct nlmsghdr *nlh;
627
 
628
        nlh = nlmsg_put(skb, pid, seq, type, sizeof(*ifm), flags);
629
        if (nlh == NULL)
630
                return -EMSGSIZE;
631
 
632
        ifm = nlmsg_data(nlh);
633
        ifm->ifi_family = AF_UNSPEC;
634
        ifm->__ifi_pad = 0;
635
        ifm->ifi_type = dev->type;
636
        ifm->ifi_index = dev->ifindex;
637
        ifm->ifi_flags = dev_get_flags(dev);
638
        ifm->ifi_change = change;
639
 
640
        NLA_PUT_STRING(skb, IFLA_IFNAME, dev->name);
641
        NLA_PUT_U32(skb, IFLA_TXQLEN, dev->tx_queue_len);
642
        NLA_PUT_U8(skb, IFLA_OPERSTATE,
643
                   netif_running(dev) ? dev->operstate : IF_OPER_DOWN);
644
        NLA_PUT_U8(skb, IFLA_LINKMODE, dev->link_mode);
645
        NLA_PUT_U32(skb, IFLA_MTU, dev->mtu);
646
 
647
        if (dev->ifindex != dev->iflink)
648
                NLA_PUT_U32(skb, IFLA_LINK, dev->iflink);
649
 
650
        if (dev->master)
651
                NLA_PUT_U32(skb, IFLA_MASTER, dev->master->ifindex);
652
 
653
        if (dev->qdisc_sleeping)
654
                NLA_PUT_STRING(skb, IFLA_QDISC, dev->qdisc_sleeping->ops->id);
655
 
656
        if (1) {
657
                struct rtnl_link_ifmap map = {
658
                        .mem_start   = dev->mem_start,
659
                        .mem_end     = dev->mem_end,
660
                        .base_addr   = dev->base_addr,
661
                        .irq         = dev->irq,
662
                        .dma         = dev->dma,
663
                        .port        = dev->if_port,
664
                };
665
                NLA_PUT(skb, IFLA_MAP, sizeof(map), &map);
666
        }
667
 
668
        if (dev->addr_len) {
669
                NLA_PUT(skb, IFLA_ADDRESS, dev->addr_len, dev->dev_addr);
670
                NLA_PUT(skb, IFLA_BROADCAST, dev->addr_len, dev->broadcast);
671
        }
672
 
673
        if (dev->get_stats) {
674
                struct net_device_stats *stats = dev->get_stats(dev);
675
                if (stats) {
676
                        struct nlattr *attr;
677
 
678
                        attr = nla_reserve(skb, IFLA_STATS,
679
                                           sizeof(struct rtnl_link_stats));
680
                        if (attr == NULL)
681
                                goto nla_put_failure;
682
 
683
                        copy_rtnl_link_stats(nla_data(attr), stats);
684
                }
685
        }
686
 
687
        if (dev->rtnl_link_ops) {
688
                if (rtnl_link_fill(skb, dev) < 0)
689
                        goto nla_put_failure;
690
        }
691
 
692
        return nlmsg_end(skb, nlh);
693
 
694
nla_put_failure:
695
        nlmsg_cancel(skb, nlh);
696
        return -EMSGSIZE;
697
}
698
 
699
static int rtnl_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb)
700
{
701
        struct net *net = skb->sk->sk_net;
702
        int idx;
703
        int s_idx = cb->args[0];
704
        struct net_device *dev;
705
 
706
        idx = 0;
707
        for_each_netdev(net, dev) {
708
                if (idx < s_idx)
709
                        goto cont;
710
                if (rtnl_fill_ifinfo(skb, dev, RTM_NEWLINK,
711
                                     NETLINK_CB(cb->skb).pid,
712
                                     cb->nlh->nlmsg_seq, 0, NLM_F_MULTI) <= 0)
713
                        break;
714
cont:
715
                idx++;
716
        }
717
        cb->args[0] = idx;
718
 
719
        return skb->len;
720
}
721
 
722
const struct nla_policy ifla_policy[IFLA_MAX+1] = {
723
        [IFLA_IFNAME]           = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
724
        [IFLA_ADDRESS]          = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
725
        [IFLA_BROADCAST]        = { .type = NLA_BINARY, .len = MAX_ADDR_LEN },
726
        [IFLA_MAP]              = { .len = sizeof(struct rtnl_link_ifmap) },
727
        [IFLA_MTU]              = { .type = NLA_U32 },
728
        [IFLA_TXQLEN]           = { .type = NLA_U32 },
729
        [IFLA_WEIGHT]           = { .type = NLA_U32 },
730
        [IFLA_OPERSTATE]        = { .type = NLA_U8 },
731
        [IFLA_LINKMODE]         = { .type = NLA_U8 },
732
        [IFLA_NET_NS_PID]       = { .type = NLA_U32 },
733
};
734
 
735
static const struct nla_policy ifla_info_policy[IFLA_INFO_MAX+1] = {
736
        [IFLA_INFO_KIND]        = { .type = NLA_STRING },
737
        [IFLA_INFO_DATA]        = { .type = NLA_NESTED },
738
};
739
 
740
static struct net *get_net_ns_by_pid(pid_t pid)
741
{
742
        struct task_struct *tsk;
743
        struct net *net;
744
 
745
        /* Lookup the network namespace */
746
        net = ERR_PTR(-ESRCH);
747
        rcu_read_lock();
748
        tsk = find_task_by_vpid(pid);
749
        if (tsk) {
750
                struct nsproxy *nsproxy;
751
                nsproxy = task_nsproxy(tsk);
752
                if (nsproxy)
753
                        net = get_net(nsproxy->net_ns);
754
        }
755
        rcu_read_unlock();
756
        return net;
757
}
758
 
759
static int do_setlink(struct net_device *dev, struct ifinfomsg *ifm,
760
                      struct nlattr **tb, char *ifname, int modified)
761
{
762
        int send_addr_notify = 0;
763
        int err;
764
 
765
        if (tb[IFLA_NET_NS_PID]) {
766
                struct net *net;
767
                net = get_net_ns_by_pid(nla_get_u32(tb[IFLA_NET_NS_PID]));
768
                if (IS_ERR(net)) {
769
                        err = PTR_ERR(net);
770
                        goto errout;
771
                }
772
                err = dev_change_net_namespace(dev, net, ifname);
773
                put_net(net);
774
                if (err)
775
                        goto errout;
776
                modified = 1;
777
        }
778
 
779
        if (tb[IFLA_MAP]) {
780
                struct rtnl_link_ifmap *u_map;
781
                struct ifmap k_map;
782
 
783
                if (!dev->set_config) {
784
                        err = -EOPNOTSUPP;
785
                        goto errout;
786
                }
787
 
788
                if (!netif_device_present(dev)) {
789
                        err = -ENODEV;
790
                        goto errout;
791
                }
792
 
793
                u_map = nla_data(tb[IFLA_MAP]);
794
                k_map.mem_start = (unsigned long) u_map->mem_start;
795
                k_map.mem_end = (unsigned long) u_map->mem_end;
796
                k_map.base_addr = (unsigned short) u_map->base_addr;
797
                k_map.irq = (unsigned char) u_map->irq;
798
                k_map.dma = (unsigned char) u_map->dma;
799
                k_map.port = (unsigned char) u_map->port;
800
 
801
                err = dev->set_config(dev, &k_map);
802
                if (err < 0)
803
                        goto errout;
804
 
805
                modified = 1;
806
        }
807
 
808
        if (tb[IFLA_ADDRESS]) {
809
                struct sockaddr *sa;
810
                int len;
811
 
812
                if (!dev->set_mac_address) {
813
                        err = -EOPNOTSUPP;
814
                        goto errout;
815
                }
816
 
817
                if (!netif_device_present(dev)) {
818
                        err = -ENODEV;
819
                        goto errout;
820
                }
821
 
822
                len = sizeof(sa_family_t) + dev->addr_len;
823
                sa = kmalloc(len, GFP_KERNEL);
824
                if (!sa) {
825
                        err = -ENOMEM;
826
                        goto errout;
827
                }
828
                sa->sa_family = dev->type;
829
                memcpy(sa->sa_data, nla_data(tb[IFLA_ADDRESS]),
830
                       dev->addr_len);
831
                err = dev->set_mac_address(dev, sa);
832
                kfree(sa);
833
                if (err)
834
                        goto errout;
835
                send_addr_notify = 1;
836
                modified = 1;
837
        }
838
 
839
        if (tb[IFLA_MTU]) {
840
                err = dev_set_mtu(dev, nla_get_u32(tb[IFLA_MTU]));
841
                if (err < 0)
842
                        goto errout;
843
                modified = 1;
844
        }
845
 
846
        /*
847
         * Interface selected by interface index but interface
848
         * name provided implies that a name change has been
849
         * requested.
850
         */
851
        if (ifm->ifi_index > 0 && ifname[0]) {
852
                err = dev_change_name(dev, ifname);
853
                if (err < 0)
854
                        goto errout;
855
                modified = 1;
856
        }
857
 
858
        if (tb[IFLA_BROADCAST]) {
859
                nla_memcpy(dev->broadcast, tb[IFLA_BROADCAST], dev->addr_len);
860
                send_addr_notify = 1;
861
        }
862
 
863
        if (ifm->ifi_flags || ifm->ifi_change) {
864
                unsigned int flags = ifm->ifi_flags;
865
 
866
                /* bugwards compatibility: ifi_change == 0 is treated as ~0 */
867
                if (ifm->ifi_change)
868
                        flags = (flags & ifm->ifi_change) |
869
                                (dev->flags & ~ifm->ifi_change);
870
                dev_change_flags(dev, flags);
871
        }
872
 
873
        if (tb[IFLA_TXQLEN])
874
                dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
875
 
876
        if (tb[IFLA_OPERSTATE])
877
                set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
878
 
879
        if (tb[IFLA_LINKMODE]) {
880
                write_lock_bh(&dev_base_lock);
881
                dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
882
                write_unlock_bh(&dev_base_lock);
883
        }
884
 
885
        err = 0;
886
 
887
errout:
888
        if (err < 0 && modified && net_ratelimit())
889
                printk(KERN_WARNING "A link change request failed with "
890
                       "some changes comitted already. Interface %s may "
891
                       "have been left with an inconsistent configuration, "
892
                       "please check.\n", dev->name);
893
 
894
        if (send_addr_notify)
895
                call_netdevice_notifiers(NETDEV_CHANGEADDR, dev);
896
        return err;
897
}
898
 
899
static int rtnl_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
900
{
901
        struct net *net = skb->sk->sk_net;
902
        struct ifinfomsg *ifm;
903
        struct net_device *dev;
904
        int err;
905
        struct nlattr *tb[IFLA_MAX+1];
906
        char ifname[IFNAMSIZ];
907
 
908
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
909
        if (err < 0)
910
                goto errout;
911
 
912
        if (tb[IFLA_IFNAME])
913
                nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
914
        else
915
                ifname[0] = '\0';
916
 
917
        err = -EINVAL;
918
        ifm = nlmsg_data(nlh);
919
        if (ifm->ifi_index > 0)
920
                dev = dev_get_by_index(net, ifm->ifi_index);
921
        else if (tb[IFLA_IFNAME])
922
                dev = dev_get_by_name(net, ifname);
923
        else
924
                goto errout;
925
 
926
        if (dev == NULL) {
927
                err = -ENODEV;
928
                goto errout;
929
        }
930
 
931
        if (tb[IFLA_ADDRESS] &&
932
            nla_len(tb[IFLA_ADDRESS]) < dev->addr_len)
933
                goto errout_dev;
934
 
935
        if (tb[IFLA_BROADCAST] &&
936
            nla_len(tb[IFLA_BROADCAST]) < dev->addr_len)
937
                goto errout_dev;
938
 
939
        err = do_setlink(dev, ifm, tb, ifname, 0);
940
errout_dev:
941
        dev_put(dev);
942
errout:
943
        return err;
944
}
945
 
946
static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
947
{
948
        struct net *net = skb->sk->sk_net;
949
        const struct rtnl_link_ops *ops;
950
        struct net_device *dev;
951
        struct ifinfomsg *ifm;
952
        char ifname[IFNAMSIZ];
953
        struct nlattr *tb[IFLA_MAX+1];
954
        int err;
955
 
956
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
957
        if (err < 0)
958
                return err;
959
 
960
        if (tb[IFLA_IFNAME])
961
                nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
962
 
963
        ifm = nlmsg_data(nlh);
964
        if (ifm->ifi_index > 0)
965
                dev = __dev_get_by_index(net, ifm->ifi_index);
966
        else if (tb[IFLA_IFNAME])
967
                dev = __dev_get_by_name(net, ifname);
968
        else
969
                return -EINVAL;
970
 
971
        if (!dev)
972
                return -ENODEV;
973
 
974
        ops = dev->rtnl_link_ops;
975
        if (!ops)
976
                return -EOPNOTSUPP;
977
 
978
        ops->dellink(dev);
979
        return 0;
980
}
981
 
982
struct net_device *rtnl_create_link(struct net *net, char *ifname,
983
                const struct rtnl_link_ops *ops, struct nlattr *tb[])
984
{
985
        int err;
986
        struct net_device *dev;
987
 
988
        err = -ENOMEM;
989
        dev = alloc_netdev(ops->priv_size, ifname, ops->setup);
990
        if (!dev)
991
                goto err;
992
 
993
        if (strchr(dev->name, '%')) {
994
                err = dev_alloc_name(dev, dev->name);
995
                if (err < 0)
996
                        goto err_free;
997
        }
998
 
999
        dev->nd_net = net;
1000
        dev->rtnl_link_ops = ops;
1001
 
1002
        if (tb[IFLA_MTU])
1003
                dev->mtu = nla_get_u32(tb[IFLA_MTU]);
1004
        if (tb[IFLA_ADDRESS])
1005
                memcpy(dev->dev_addr, nla_data(tb[IFLA_ADDRESS]),
1006
                                nla_len(tb[IFLA_ADDRESS]));
1007
        if (tb[IFLA_BROADCAST])
1008
                memcpy(dev->broadcast, nla_data(tb[IFLA_BROADCAST]),
1009
                                nla_len(tb[IFLA_BROADCAST]));
1010
        if (tb[IFLA_TXQLEN])
1011
                dev->tx_queue_len = nla_get_u32(tb[IFLA_TXQLEN]);
1012
        if (tb[IFLA_OPERSTATE])
1013
                set_operstate(dev, nla_get_u8(tb[IFLA_OPERSTATE]));
1014
        if (tb[IFLA_LINKMODE])
1015
                dev->link_mode = nla_get_u8(tb[IFLA_LINKMODE]);
1016
 
1017
        return dev;
1018
 
1019
err_free:
1020
        free_netdev(dev);
1021
err:
1022
        return ERR_PTR(err);
1023
}
1024
 
1025
static int rtnl_newlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
1026
{
1027
        struct net *net = skb->sk->sk_net;
1028
        const struct rtnl_link_ops *ops;
1029
        struct net_device *dev;
1030
        struct ifinfomsg *ifm;
1031
        char kind[MODULE_NAME_LEN];
1032
        char ifname[IFNAMSIZ];
1033
        struct nlattr *tb[IFLA_MAX+1];
1034
        struct nlattr *linkinfo[IFLA_INFO_MAX+1];
1035
        int err;
1036
 
1037
#ifdef CONFIG_KMOD
1038
replay:
1039
#endif
1040
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
1041
        if (err < 0)
1042
                return err;
1043
 
1044
        if (tb[IFLA_IFNAME])
1045
                nla_strlcpy(ifname, tb[IFLA_IFNAME], IFNAMSIZ);
1046
        else
1047
                ifname[0] = '\0';
1048
 
1049
        ifm = nlmsg_data(nlh);
1050
        if (ifm->ifi_index > 0)
1051
                dev = __dev_get_by_index(net, ifm->ifi_index);
1052
        else if (ifname[0])
1053
                dev = __dev_get_by_name(net, ifname);
1054
        else
1055
                dev = NULL;
1056
 
1057
        if (tb[IFLA_LINKINFO]) {
1058
                err = nla_parse_nested(linkinfo, IFLA_INFO_MAX,
1059
                                       tb[IFLA_LINKINFO], ifla_info_policy);
1060
                if (err < 0)
1061
                        return err;
1062
        } else
1063
                memset(linkinfo, 0, sizeof(linkinfo));
1064
 
1065
        if (linkinfo[IFLA_INFO_KIND]) {
1066
                nla_strlcpy(kind, linkinfo[IFLA_INFO_KIND], sizeof(kind));
1067
                ops = rtnl_link_ops_get(kind);
1068
        } else {
1069
                kind[0] = '\0';
1070
                ops = NULL;
1071
        }
1072
 
1073
        if (1) {
1074
                struct nlattr *attr[ops ? ops->maxtype + 1 : 0], **data = NULL;
1075
 
1076
                if (ops) {
1077
                        if (ops->maxtype && linkinfo[IFLA_INFO_DATA]) {
1078
                                err = nla_parse_nested(attr, ops->maxtype,
1079
                                                       linkinfo[IFLA_INFO_DATA],
1080
                                                       ops->policy);
1081
                                if (err < 0)
1082
                                        return err;
1083
                                data = attr;
1084
                        }
1085
                        if (ops->validate) {
1086
                                err = ops->validate(tb, data);
1087
                                if (err < 0)
1088
                                        return err;
1089
                        }
1090
                }
1091
 
1092
                if (dev) {
1093
                        int modified = 0;
1094
 
1095
                        if (nlh->nlmsg_flags & NLM_F_EXCL)
1096
                                return -EEXIST;
1097
                        if (nlh->nlmsg_flags & NLM_F_REPLACE)
1098
                                return -EOPNOTSUPP;
1099
 
1100
                        if (linkinfo[IFLA_INFO_DATA]) {
1101
                                if (!ops || ops != dev->rtnl_link_ops ||
1102
                                    !ops->changelink)
1103
                                        return -EOPNOTSUPP;
1104
 
1105
                                err = ops->changelink(dev, tb, data);
1106
                                if (err < 0)
1107
                                        return err;
1108
                                modified = 1;
1109
                        }
1110
 
1111
                        return do_setlink(dev, ifm, tb, ifname, modified);
1112
                }
1113
 
1114
                if (!(nlh->nlmsg_flags & NLM_F_CREATE))
1115
                        return -ENODEV;
1116
 
1117
                if (ifm->ifi_index || ifm->ifi_flags || ifm->ifi_change)
1118
                        return -EOPNOTSUPP;
1119
                if (tb[IFLA_MAP] || tb[IFLA_MASTER] || tb[IFLA_PROTINFO])
1120
                        return -EOPNOTSUPP;
1121
 
1122
                if (!ops) {
1123
#ifdef CONFIG_KMOD
1124
                        if (kind[0]) {
1125
                                __rtnl_unlock();
1126
                                request_module("rtnl-link-%s", kind);
1127
                                rtnl_lock();
1128
                                ops = rtnl_link_ops_get(kind);
1129
                                if (ops)
1130
                                        goto replay;
1131
                        }
1132
#endif
1133
                        return -EOPNOTSUPP;
1134
                }
1135
 
1136
                if (!ifname[0])
1137
                        snprintf(ifname, IFNAMSIZ, "%s%%d", ops->kind);
1138
 
1139
                dev = rtnl_create_link(net, ifname, ops, tb);
1140
 
1141
                if (IS_ERR(dev))
1142
                        err = PTR_ERR(dev);
1143
                else if (ops->newlink)
1144
                        err = ops->newlink(dev, tb, data);
1145
                else
1146
                        err = register_netdevice(dev);
1147
 
1148
                if (err < 0 && !IS_ERR(dev))
1149
                        free_netdev(dev);
1150
                return err;
1151
        }
1152
}
1153
 
1154
static int rtnl_getlink(struct sk_buff *skb, struct nlmsghdr* nlh, void *arg)
1155
{
1156
        struct net *net = skb->sk->sk_net;
1157
        struct ifinfomsg *ifm;
1158
        struct nlattr *tb[IFLA_MAX+1];
1159
        struct net_device *dev = NULL;
1160
        struct sk_buff *nskb;
1161
        int err;
1162
 
1163
        err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFLA_MAX, ifla_policy);
1164
        if (err < 0)
1165
                return err;
1166
 
1167
        ifm = nlmsg_data(nlh);
1168
        if (ifm->ifi_index > 0) {
1169
                dev = dev_get_by_index(net, ifm->ifi_index);
1170
                if (dev == NULL)
1171
                        return -ENODEV;
1172
        } else
1173
                return -EINVAL;
1174
 
1175
        nskb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
1176
        if (nskb == NULL) {
1177
                err = -ENOBUFS;
1178
                goto errout;
1179
        }
1180
 
1181
        err = rtnl_fill_ifinfo(nskb, dev, RTM_NEWLINK, NETLINK_CB(skb).pid,
1182
                               nlh->nlmsg_seq, 0, 0);
1183
        if (err < 0) {
1184
                /* -EMSGSIZE implies BUG in if_nlmsg_size */
1185
                WARN_ON(err == -EMSGSIZE);
1186
                kfree_skb(nskb);
1187
                goto errout;
1188
        }
1189
        err = rtnl_unicast(nskb, NETLINK_CB(skb).pid);
1190
errout:
1191
        dev_put(dev);
1192
 
1193
        return err;
1194
}
1195
 
1196
static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
1197
{
1198
        int idx;
1199
        int s_idx = cb->family;
1200
 
1201
        if (s_idx == 0)
1202
                s_idx = 1;
1203
        for (idx=1; idx<NPROTO; idx++) {
1204
                int type = cb->nlh->nlmsg_type-RTM_BASE;
1205
                if (idx < s_idx || idx == PF_PACKET)
1206
                        continue;
1207
                if (rtnl_msg_handlers[idx] == NULL ||
1208
                    rtnl_msg_handlers[idx][type].dumpit == NULL)
1209
                        continue;
1210
                if (idx > s_idx)
1211
                        memset(&cb->args[0], 0, sizeof(cb->args));
1212
                if (rtnl_msg_handlers[idx][type].dumpit(skb, cb))
1213
                        break;
1214
        }
1215
        cb->family = idx;
1216
 
1217
        return skb->len;
1218
}
1219
 
1220
void rtmsg_ifinfo(int type, struct net_device *dev, unsigned change)
1221
{
1222
        struct sk_buff *skb;
1223
        int err = -ENOBUFS;
1224
 
1225
        skb = nlmsg_new(if_nlmsg_size(dev), GFP_KERNEL);
1226
        if (skb == NULL)
1227
                goto errout;
1228
 
1229
        err = rtnl_fill_ifinfo(skb, dev, type, 0, 0, change, 0);
1230
        if (err < 0) {
1231
                /* -EMSGSIZE implies BUG in if_nlmsg_size() */
1232
                WARN_ON(err == -EMSGSIZE);
1233
                kfree_skb(skb);
1234
                goto errout;
1235
        }
1236
        err = rtnl_notify(skb, 0, RTNLGRP_LINK, NULL, GFP_KERNEL);
1237
errout:
1238
        if (err < 0)
1239
                rtnl_set_sk_err(RTNLGRP_LINK, err);
1240
}
1241
 
1242
/* Protected by RTNL sempahore.  */
1243
static struct rtattr **rta_buf;
1244
static int rtattr_max;
1245
 
1246
/* Process one rtnetlink message. */
1247
 
1248
static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
1249
{
1250
        rtnl_doit_func doit;
1251
        int sz_idx, kind;
1252
        int min_len;
1253
        int family;
1254
        int type;
1255
        int err;
1256
 
1257
        type = nlh->nlmsg_type;
1258
        if (type > RTM_MAX)
1259
                return -EOPNOTSUPP;
1260
 
1261
        type -= RTM_BASE;
1262
 
1263
        /* All the messages must have at least 1 byte length */
1264
        if (nlh->nlmsg_len < NLMSG_LENGTH(sizeof(struct rtgenmsg)))
1265
                return 0;
1266
 
1267
        family = ((struct rtgenmsg*)NLMSG_DATA(nlh))->rtgen_family;
1268
        if (family >= NPROTO)
1269
                return -EAFNOSUPPORT;
1270
 
1271
        sz_idx = type>>2;
1272
        kind = type&3;
1273
 
1274
        if (kind != 2 && security_netlink_recv(skb, CAP_NET_ADMIN))
1275
                return -EPERM;
1276
 
1277
        if (kind == 2 && nlh->nlmsg_flags&NLM_F_DUMP) {
1278
                rtnl_dumpit_func dumpit;
1279
 
1280
                dumpit = rtnl_get_dumpit(family, type);
1281
                if (dumpit == NULL)
1282
                        return -EOPNOTSUPP;
1283
 
1284
                __rtnl_unlock();
1285
                err = netlink_dump_start(rtnl, skb, nlh, dumpit, NULL);
1286
                rtnl_lock();
1287
                return err;
1288
        }
1289
 
1290
        memset(rta_buf, 0, (rtattr_max * sizeof(struct rtattr *)));
1291
 
1292
        min_len = rtm_min[sz_idx];
1293
        if (nlh->nlmsg_len < min_len)
1294
                return -EINVAL;
1295
 
1296
        if (nlh->nlmsg_len > min_len) {
1297
                int attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
1298
                struct rtattr *attr = (void*)nlh + NLMSG_ALIGN(min_len);
1299
 
1300
                while (RTA_OK(attr, attrlen)) {
1301
                        unsigned flavor = attr->rta_type;
1302
                        if (flavor) {
1303
                                if (flavor > rta_max[sz_idx])
1304
                                        return -EINVAL;
1305
                                rta_buf[flavor-1] = attr;
1306
                        }
1307
                        attr = RTA_NEXT(attr, attrlen);
1308
                }
1309
        }
1310
 
1311
        doit = rtnl_get_doit(family, type);
1312
        if (doit == NULL)
1313
                return -EOPNOTSUPP;
1314
 
1315
        return doit(skb, nlh, (void *)&rta_buf[0]);
1316
}
1317
 
1318
static void rtnetlink_rcv(struct sk_buff *skb)
1319
{
1320
        rtnl_lock();
1321
        netlink_rcv_skb(skb, &rtnetlink_rcv_msg);
1322
        rtnl_unlock();
1323
}
1324
 
1325
static int rtnetlink_event(struct notifier_block *this, unsigned long event, void *ptr)
1326
{
1327
        struct net_device *dev = ptr;
1328
 
1329
        if (dev->nd_net != &init_net)
1330
                return NOTIFY_DONE;
1331
 
1332
        switch (event) {
1333
        case NETDEV_UNREGISTER:
1334
                rtmsg_ifinfo(RTM_DELLINK, dev, ~0U);
1335
                break;
1336
        case NETDEV_REGISTER:
1337
                rtmsg_ifinfo(RTM_NEWLINK, dev, ~0U);
1338
                break;
1339
        case NETDEV_UP:
1340
        case NETDEV_DOWN:
1341
                rtmsg_ifinfo(RTM_NEWLINK, dev, IFF_UP|IFF_RUNNING);
1342
                break;
1343
        case NETDEV_CHANGE:
1344
        case NETDEV_GOING_DOWN:
1345
                break;
1346
        default:
1347
                rtmsg_ifinfo(RTM_NEWLINK, dev, 0);
1348
                break;
1349
        }
1350
        return NOTIFY_DONE;
1351
}
1352
 
1353
static struct notifier_block rtnetlink_dev_notifier = {
1354
        .notifier_call  = rtnetlink_event,
1355
};
1356
 
1357
void __init rtnetlink_init(void)
1358
{
1359
        int i;
1360
 
1361
        rtattr_max = 0;
1362
        for (i = 0; i < ARRAY_SIZE(rta_max); i++)
1363
                if (rta_max[i] > rtattr_max)
1364
                        rtattr_max = rta_max[i];
1365
        rta_buf = kmalloc(rtattr_max * sizeof(struct rtattr *), GFP_KERNEL);
1366
        if (!rta_buf)
1367
                panic("rtnetlink_init: cannot allocate rta_buf\n");
1368
 
1369
        rtnl = netlink_kernel_create(&init_net, NETLINK_ROUTE, RTNLGRP_MAX,
1370
                                     rtnetlink_rcv, &rtnl_mutex, THIS_MODULE);
1371
        if (rtnl == NULL)
1372
                panic("rtnetlink_init: cannot initialize rtnetlink\n");
1373
        netlink_set_nonroot(NETLINK_ROUTE, NL_NONROOT_RECV);
1374
        register_netdevice_notifier(&rtnetlink_dev_notifier);
1375
 
1376
        rtnl_register(PF_UNSPEC, RTM_GETLINK, rtnl_getlink, rtnl_dump_ifinfo);
1377
        rtnl_register(PF_UNSPEC, RTM_SETLINK, rtnl_setlink, NULL);
1378
        rtnl_register(PF_UNSPEC, RTM_NEWLINK, rtnl_newlink, NULL);
1379
        rtnl_register(PF_UNSPEC, RTM_DELLINK, rtnl_dellink, NULL);
1380
 
1381
        rtnl_register(PF_UNSPEC, RTM_GETADDR, NULL, rtnl_dump_all);
1382
        rtnl_register(PF_UNSPEC, RTM_GETROUTE, NULL, rtnl_dump_all);
1383
}
1384
 
1385
EXPORT_SYMBOL(__rta_fill);
1386
EXPORT_SYMBOL(rtattr_strlcpy);
1387
EXPORT_SYMBOL(rtattr_parse);
1388
EXPORT_SYMBOL(__rtattr_parse_nested_compat);
1389
EXPORT_SYMBOL(rtnetlink_put_metrics);
1390
EXPORT_SYMBOL(rtnl_lock);
1391
EXPORT_SYMBOL(rtnl_trylock);
1392
EXPORT_SYMBOL(rtnl_unlock);
1393
EXPORT_SYMBOL(rtnl_unicast);
1394
EXPORT_SYMBOL(rtnl_notify);
1395
EXPORT_SYMBOL(rtnl_set_sk_err);
1396
EXPORT_SYMBOL(rtnl_create_link);
1397
EXPORT_SYMBOL(ifla_policy);

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.