~ubuntu-branches/ubuntu/trusty/libnl3/trusty

« back to all changes in this revision

Viewing changes to lib/route/link/inet6.c

  • Committer: Bazaar Package Importer
  • Author(s): Heiko Stuebner
  • Date: 2011-05-21 19:25:13 UTC
  • Revision ID: james.westby@ubuntu.com-20110521192513-1ieyu9w9kym4bt16
Tags: upstream-3.0
ImportĀ upstreamĀ versionĀ 3.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * lib/route/link/inet6.c       AF_INET6 link operations
 
3
 *
 
4
 *      This library is free software; you can redistribute it and/or
 
5
 *      modify it under the terms of the GNU Lesser General Public
 
6
 *      License as published by the Free Software Foundation version 2.1
 
7
 *      of the License.
 
8
 *
 
9
 * Copyright (c) 2010 Thomas Graf <tgraf@suug.ch>
 
10
 */
 
11
 
 
12
#include <netlink-local.h>
 
13
#include <netlink/netlink.h>
 
14
#include <netlink/attr.h>
 
15
#include <netlink/route/rtnl.h>
 
16
#include <netlink/route/link/api.h>
 
17
 
 
18
struct inet6_data
 
19
{
 
20
        uint32_t                i6_flags;
 
21
        struct ifla_cacheinfo   i6_cacheinfo;
 
22
        uint32_t                i6_conf[DEVCONF_MAX];
 
23
};
 
24
 
 
25
static void *inet6_alloc(struct rtnl_link *link)
 
26
{
 
27
        return calloc(1, sizeof(struct inet6_data));
 
28
}
 
29
 
 
30
static void *inet6_clone(struct rtnl_link *link, void *data)
 
31
{
 
32
        struct inet6_data *i6;
 
33
 
 
34
        if ((i6 = inet6_alloc(link)))
 
35
                memcpy(i6, data, sizeof(*i6));
 
36
 
 
37
        return i6;
 
38
}
 
39
 
 
40
static void inet6_free(struct rtnl_link *link, void *data)
 
41
{
 
42
        free(data);
 
43
}
 
44
 
 
45
static struct nla_policy inet6_policy[IFLA_INET6_MAX+1] = {
 
46
        [IFLA_INET6_FLAGS]      = { .type = NLA_U32 },
 
47
        [IFLA_INET6_CACHEINFO]  = { .minlen = sizeof(struct ifla_cacheinfo) },
 
48
        [IFLA_INET6_CONF]       = { .minlen = DEVCONF_MAX * 4 },
 
49
        [IFLA_INET6_STATS]      = { .minlen = __IPSTATS_MIB_MAX * 8 },
 
50
        [IFLA_INET6_ICMP6STATS] = { .minlen = __ICMP6_MIB_MAX * 8 },
 
51
};
 
52
 
 
53
static int inet6_parse_protinfo(struct rtnl_link *link, struct nlattr *attr,
 
54
                                void *data)
 
55
{
 
56
        struct inet6_data *i6 = data;
 
57
        struct nlattr *tb[IFLA_INET6_MAX+1];
 
58
        int err;
 
59
 
 
60
        err = nla_parse_nested(tb, IFLA_INET6_MAX, attr, inet6_policy);
 
61
        if (err < 0)
 
62
                return err;
 
63
 
 
64
        if (tb[IFLA_INET6_FLAGS])
 
65
                i6->i6_flags = nla_get_u32(tb[IFLA_INET6_FLAGS]);
 
66
 
 
67
        if (tb[IFLA_INET6_CACHEINFO])
 
68
                nla_memcpy(&i6->i6_cacheinfo, tb[IFLA_INET6_CACHEINFO],
 
69
                           sizeof(i6->i6_cacheinfo));
 
70
 
 
71
        if (tb[IFLA_INET6_CONF])
 
72
                nla_memcpy(&i6->i6_conf, tb[IFLA_INET6_CONF],
 
73
                           sizeof(i6->i6_conf));
 
74
 
 
75
        if (tb[IFLA_INET6_STATS]) {
 
76
                uint64_t *cnt = nla_data(tb[IFLA_INET6_STATS]);
 
77
                int i;
 
78
 
 
79
                for (i = 1; i < __IPSTATS_MIB_MAX; i++)
 
80
                        rtnl_link_set_stat(link, RTNL_LINK_IP6_INPKTS + i - 1,
 
81
                                           cnt[i]);
 
82
        }
 
83
 
 
84
        if (tb[IFLA_INET6_ICMP6STATS]) {
 
85
                uint64_t *cnt = nla_data(tb[IFLA_INET6_ICMP6STATS]);
 
86
                int i;
 
87
 
 
88
                for (i = 1; i < __ICMP6_MIB_MAX; i++)
 
89
                        rtnl_link_set_stat(link, RTNL_LINK_ICMP6_INMSGS + i - 1,
 
90
                                           cnt[i]);
 
91
        }
 
92
 
 
93
        return 0;
 
94
}
 
95
 
 
96
/* These live in include/net/if_inet6.h and should be moved to include/linux */
 
97
#define IF_RA_OTHERCONF 0x80
 
98
#define IF_RA_MANAGED   0x40
 
99
#define IF_RA_RCVD      0x20
 
100
#define IF_RS_SENT      0x10
 
101
#define IF_READY        0x80000000
 
102
 
 
103
static const struct trans_tbl inet6_flags[] = {
 
104
        __ADD(IF_RA_OTHERCONF, ra_otherconf)
 
105
        __ADD(IF_RA_MANAGED, ra_managed)
 
106
        __ADD(IF_RA_RCVD, ra_rcvd)
 
107
        __ADD(IF_RS_SENT, rs_sent)
 
108
        __ADD(IF_READY, ready)
 
109
};
 
110
 
 
111
static char *inet6_flags2str(int flags, char *buf, size_t len)
 
112
{
 
113
        return __flags2str(flags, buf, len, inet6_flags,
 
114
                           ARRAY_SIZE(inet6_flags));
 
115
}
 
116
 
 
117
static const struct trans_tbl inet6_devconf[] = {
 
118
        __ADD(DEVCONF_FORWARDING, forwarding)
 
119
        __ADD(DEVCONF_HOPLIMIT, hoplimit)
 
120
        __ADD(DEVCONF_MTU6, mtu6)
 
121
        __ADD(DEVCONF_ACCEPT_RA, accept_ra)
 
122
        __ADD(DEVCONF_ACCEPT_REDIRECTS, accept_redirects)
 
123
        __ADD(DEVCONF_AUTOCONF, autoconf)
 
124
        __ADD(DEVCONF_DAD_TRANSMITS, dad_transmits)
 
125
        __ADD(DEVCONF_RTR_SOLICITS, rtr_solicits)
 
126
        __ADD(DEVCONF_RTR_SOLICIT_INTERVAL, rtr_solicit_interval)
 
127
        __ADD(DEVCONF_RTR_SOLICIT_DELAY, rtr_solicit_delay)
 
128
        __ADD(DEVCONF_USE_TEMPADDR, use_tempaddr)
 
129
        __ADD(DEVCONF_TEMP_VALID_LFT, temp_valid_lft)
 
130
        __ADD(DEVCONF_TEMP_PREFERED_LFT, temp_prefered_lft)
 
131
        __ADD(DEVCONF_REGEN_MAX_RETRY, regen_max_retry)
 
132
        __ADD(DEVCONF_MAX_DESYNC_FACTOR, max_desync_factor)
 
133
        __ADD(DEVCONF_MAX_ADDRESSES, max_addresses)
 
134
        __ADD(DEVCONF_FORCE_MLD_VERSION, force_mld_version)
 
135
        __ADD(DEVCONF_ACCEPT_RA_DEFRTR, accept_ra_defrtr)
 
136
        __ADD(DEVCONF_ACCEPT_RA_PINFO, accept_ra_pinfo)
 
137
        __ADD(DEVCONF_ACCEPT_RA_RTR_PREF, accept_ra_rtr_pref)
 
138
        __ADD(DEVCONF_RTR_PROBE_INTERVAL, rtr_probe_interval)
 
139
        __ADD(DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN, accept_ra_rt_info)
 
140
        __ADD(DEVCONF_PROXY_NDP, proxy_ndp)
 
141
        __ADD(DEVCONF_OPTIMISTIC_DAD, optimistic_dad)
 
142
        __ADD(DEVCONF_ACCEPT_SOURCE_ROUTE, accept_source_route)
 
143
        __ADD(DEVCONF_MC_FORWARDING, mc_forwarding)
 
144
        __ADD(DEVCONF_DISABLE_IPV6, disable_ipv6)
 
145
        __ADD(DEVCONF_ACCEPT_DAD, accept_dad)
 
146
        __ADD(DEVCONF_FORCE_TLLAO, force_tllao)
 
147
};
 
148
 
 
149
static char *inet6_devconf2str(int type, char *buf, size_t len)
 
150
{
 
151
        return __type2str(type, buf, len, inet6_devconf,
 
152
                          ARRAY_SIZE(inet6_devconf));
 
153
}
 
154
 
 
155
 
 
156
static void inet6_dump_details(struct rtnl_link *link,
 
157
                                struct nl_dump_params *p, void *data)
 
158
{
 
159
        struct inet6_data *i6 = data;
 
160
        char buf[64], buf2[64];
 
161
        int i, n = 0;
 
162
 
 
163
        nl_dump_line(p, "    ipv6 max-reasm-len %s",
 
164
                nl_size2str(i6->i6_cacheinfo.max_reasm_len, buf, sizeof(buf)));
 
165
 
 
166
        nl_dump(p, " <%s>\n",
 
167
                inet6_flags2str(i6->i6_flags, buf, sizeof(buf)));
 
168
 
 
169
 
 
170
        nl_dump_line(p, "      create-stamp %.2fs reachable-time %s",
 
171
                (double) i6->i6_cacheinfo.tstamp / 100.,
 
172
                nl_msec2str(i6->i6_cacheinfo.reachable_time, buf, sizeof(buf)));
 
173
 
 
174
        nl_dump(p, " retrans-time %s\n",
 
175
                nl_msec2str(i6->i6_cacheinfo.retrans_time, buf, sizeof(buf)));
 
176
 
 
177
        nl_dump_line(p, "      devconf:\n");
 
178
        nl_dump_line(p, "      ");
 
179
 
 
180
        for (i = 0; i < DEVCONF_MAX; i++) {
 
181
                uint32_t value = i6->i6_conf[i];
 
182
                int x, offset;
 
183
 
 
184
                switch (i) {
 
185
                case DEVCONF_TEMP_VALID_LFT:
 
186
                case DEVCONF_TEMP_PREFERED_LFT:
 
187
                        nl_msec2str((uint64_t) value * 1000., buf2, sizeof(buf2));
 
188
                        break;
 
189
 
 
190
                case DEVCONF_RTR_PROBE_INTERVAL:
 
191
                case DEVCONF_RTR_SOLICIT_INTERVAL:
 
192
                case DEVCONF_RTR_SOLICIT_DELAY:
 
193
                        nl_msec2str(value, buf2, sizeof(buf2));
 
194
                        break;
 
195
 
 
196
                default:
 
197
                        snprintf(buf2, sizeof(buf2), "%u", value);
 
198
                        break;
 
199
                        
 
200
                }
 
201
 
 
202
                inet6_devconf2str(i, buf, sizeof(buf));
 
203
 
 
204
                offset = 23 - strlen(buf2);
 
205
                if (offset < 0)
 
206
                        offset = 0;
 
207
 
 
208
                for (x = strlen(buf); x < offset; x++)
 
209
                        buf[x] = ' ';
 
210
 
 
211
                strncpy(&buf[offset], buf2, strlen(buf2));
 
212
 
 
213
                nl_dump_line(p, "%s", buf);
 
214
 
 
215
                if (++n == 3) {
 
216
                        nl_dump(p, "\n");
 
217
                        nl_dump_line(p, "      ");
 
218
                        n = 0;
 
219
                } else
 
220
                        nl_dump(p, "  ");
 
221
        }
 
222
 
 
223
        if (n != 0)
 
224
                nl_dump(p, "\n");
 
225
}
 
226
 
 
227
static void inet6_dump_stats(struct rtnl_link *link,
 
228
                             struct nl_dump_params *p, void *data)
 
229
{
 
230
        double octets;
 
231
        char *octetsUnit;
 
232
 
 
233
        nl_dump(p, "    IPv6:       InPkts           InOctets     "
 
234
                   "    InDiscards         InDelivers\n");
 
235
        nl_dump(p, "    %18llu ", link->l_stats[RTNL_LINK_IP6_INPKTS]);
 
236
 
 
237
        octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INOCTETS],
 
238
                                      &octetsUnit);
 
239
        if (octets)
 
240
                nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
 
241
        else
 
242
                nl_dump(p, "%16llu B ", 0);
 
243
        
 
244
        nl_dump(p, "%18llu %18llu\n",
 
245
                link->l_stats[RTNL_LINK_IP6_INDISCARDS],
 
246
                link->l_stats[RTNL_LINK_IP6_INDELIVERS]);
 
247
 
 
248
        nl_dump(p, "               OutPkts          OutOctets     "
 
249
                   "   OutDiscards        OutForwards\n");
 
250
 
 
251
        nl_dump(p, "    %18llu ", link->l_stats[RTNL_LINK_IP6_OUTPKTS]);
 
252
 
 
253
        octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTOCTETS],
 
254
                                      &octetsUnit);
 
255
        if (octets)
 
256
                nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
 
257
        else
 
258
                nl_dump(p, "%16llu B ", 0);
 
259
 
 
260
        nl_dump(p, "%18llu %18llu\n",
 
261
                link->l_stats[RTNL_LINK_IP6_OUTDISCARDS],
 
262
                link->l_stats[RTNL_LINK_IP6_OUTFORWDATAGRAMS]);
 
263
 
 
264
        nl_dump(p, "           InMcastPkts      InMcastOctets     "
 
265
                   "   InBcastPkts     InBcastOctests\n");
 
266
 
 
267
        nl_dump(p, "    %18llu ", link->l_stats[RTNL_LINK_IP6_INMCASTPKTS]);
 
268
 
 
269
        octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INMCASTOCTETS],
 
270
                                      &octetsUnit);
 
271
        if (octets)
 
272
                nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
 
273
        else
 
274
                nl_dump(p, "%16llu B ", 0);
 
275
 
 
276
        nl_dump(p, "%18llu ", link->l_stats[RTNL_LINK_IP6_INBCASTPKTS]);
 
277
        octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_INBCASTOCTETS],
 
278
                                      &octetsUnit);
 
279
        if (octets)
 
280
                nl_dump(p, "%14.2f %3s\n", octets, octetsUnit);
 
281
        else
 
282
                nl_dump(p, "%16llu B\n", 0);
 
283
 
 
284
        nl_dump(p, "          OutMcastPkts     OutMcastOctets     "
 
285
                   "  OutBcastPkts    OutBcastOctests\n");
 
286
 
 
287
        nl_dump(p, "    %18llu ", link->l_stats[RTNL_LINK_IP6_OUTMCASTPKTS]);
 
288
 
 
289
        octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTMCASTOCTETS],
 
290
                                      &octetsUnit);
 
291
        if (octets)
 
292
                nl_dump(p, "%14.2f %3s ", octets, octetsUnit);
 
293
        else
 
294
                nl_dump(p, "%16llu B ", 0);
 
295
 
 
296
        nl_dump(p, "%18llu ", link->l_stats[RTNL_LINK_IP6_OUTBCASTPKTS]);
 
297
        octets = nl_cancel_down_bytes(link->l_stats[RTNL_LINK_IP6_OUTBCASTOCTETS],
 
298
                                      &octetsUnit);
 
299
        if (octets)
 
300
                nl_dump(p, "%14.2f %3s\n", octets, octetsUnit);
 
301
        else
 
302
                nl_dump(p, "%16llu B\n", 0);
 
303
 
 
304
        nl_dump(p, "              ReasmOKs         ReasmFails     "
 
305
                   "    ReasmReqds       ReasmTimeout\n");
 
306
        nl_dump(p, "    %18llu %18llu %18llu %18llu\n",
 
307
                link->l_stats[RTNL_LINK_IP6_REASMOKS],
 
308
                link->l_stats[RTNL_LINK_IP6_REASMFAILS],
 
309
                link->l_stats[RTNL_LINK_IP6_REASMREQDS],
 
310
                link->l_stats[RTNL_LINK_IP6_REASMTIMEOUT]);
 
311
 
 
312
        nl_dump(p, "               FragOKs          FragFails    "
 
313
                   "    FragCreates\n");
 
314
        nl_dump(p, "    %18llu %18llu %18llu\n",
 
315
                link->l_stats[RTNL_LINK_IP6_FRAGOKS],
 
316
                link->l_stats[RTNL_LINK_IP6_FRAGFAILS],
 
317
                link->l_stats[RTNL_LINK_IP6_FRAGCREATES]);
 
318
 
 
319
        nl_dump(p, "           InHdrErrors      InTooBigErrors   "
 
320
                   "     InNoRoutes       InAddrErrors\n");
 
321
        nl_dump(p, "    %18llu %18llu %18llu %18llu\n",
 
322
                link->l_stats[RTNL_LINK_IP6_INHDRERRORS],
 
323
                link->l_stats[RTNL_LINK_IP6_INTOOBIGERRORS],
 
324
                link->l_stats[RTNL_LINK_IP6_INNOROUTES],
 
325
                link->l_stats[RTNL_LINK_IP6_INADDRERRORS]);
 
326
 
 
327
        nl_dump(p, "       InUnknownProtos     InTruncatedPkts   "
 
328
                   "    OutNoRoutes\n");
 
329
        nl_dump(p, "    %18llu %18llu %18llu\n",
 
330
                link->l_stats[RTNL_LINK_IP6_INUNKNOWNPROTOS],
 
331
                link->l_stats[RTNL_LINK_IP6_INTRUNCATEDPKTS],
 
332
                link->l_stats[RTNL_LINK_IP6_OUTNOROUTES]);
 
333
 
 
334
        nl_dump(p, "    ICMPv6:     InMsgs           InErrors        "
 
335
                   "    OutMsgs          OutErrors\n");
 
336
        nl_dump(p, "    %18llu %18llu %18llu %18llu\n",
 
337
                link->l_stats[RTNL_LINK_ICMP6_INMSGS],
 
338
                link->l_stats[RTNL_LINK_ICMP6_INERRORS],
 
339
                link->l_stats[RTNL_LINK_ICMP6_OUTMSGS],
 
340
                link->l_stats[RTNL_LINK_ICMP6_OUTERRORS]);
 
341
}
 
342
 
 
343
static const struct nla_policy protinfo_policy = {
 
344
        .type                   = NLA_NESTED,
 
345
};
 
346
 
 
347
static struct rtnl_link_af_ops inet6_ops = {
 
348
        .ao_family                      = AF_INET6,
 
349
        .ao_alloc                       = &inet6_alloc,
 
350
        .ao_clone                       = &inet6_clone,
 
351
        .ao_free                        = &inet6_free,
 
352
        .ao_parse_protinfo              = &inet6_parse_protinfo,
 
353
        .ao_parse_af                    = &inet6_parse_protinfo,
 
354
        .ao_dump[NL_DUMP_DETAILS]       = &inet6_dump_details,
 
355
        .ao_dump[NL_DUMP_STATS]         = &inet6_dump_stats,
 
356
        .ao_protinfo_policy             = &protinfo_policy,
 
357
};
 
358
 
 
359
static void __init inet6_init(void)
 
360
{
 
361
        rtnl_link_af_register(&inet6_ops);
 
362
}
 
363
 
 
364
static void __exit inet6_exit(void)
 
365
{
 
366
        rtnl_link_af_unregister(&inet6_ops);
 
367
}