~ubuntu-branches/ubuntu/raring/iproute/raring-proposed

« back to all changes in this revision

Viewing changes to ip/iplink_vxlan.c

  • Committer: Package Import Robot
  • Author(s): Andreas Henriksson, Kamal Mostafa
  • Date: 2012-12-12 12:29:03 UTC
  • mfrom: (23.2.7 experimental)
  • Revision ID: package-import@ubuntu.com-20121212122903-toii0ipil3vd3inj
Tags: 20121211-2
[ Kamal Mostafa ]
Enable cross-compile support in debian/rules

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * iplink_vxlan.c       VXLAN device support
 
3
 *
 
4
 *              This program is free software; you can redistribute it and/or
 
5
 *              modify it under the terms of the GNU General Public License
 
6
 *              as published by the Free Software Foundation; either version
 
7
 *              2 of the License, or (at your option) any later version.
 
8
 *
 
9
 * Authors:     Stephen Hemminger <shemminger@vyatta.com
 
10
 */
 
11
 
 
12
#include <stdio.h>
 
13
#include <stdlib.h>
 
14
#include <string.h>
 
15
#include <net/if.h>
 
16
#include <linux/ip.h>
 
17
#include <linux/if_link.h>
 
18
#include <arpa/inet.h>
 
19
 
 
20
#include "rt_names.h"
 
21
#include "utils.h"
 
22
#include "ip_common.h"
 
23
 
 
24
static void explain(void)
 
25
{
 
26
        fprintf(stderr, "Usage: ... vxlan id VNI [ group ADDR ] [ local ADDR ]\n");
 
27
        fprintf(stderr, "                 [ ttl TTL ] [ tos TOS ] [ dev PHYS_DEV ]\n");
 
28
        fprintf(stderr, "                 [ port MIN MAX ] [ [no]learning ]\n");
 
29
        fprintf(stderr, "\n");
 
30
        fprintf(stderr, "Where: VNI := 0-16777215\n");
 
31
        fprintf(stderr, "       ADDR := { IP_ADDRESS | any }\n");
 
32
        fprintf(stderr, "       TOS  := { NUMBER | inherit }\n");
 
33
        fprintf(stderr, "       TTL  := { 1..255 | inherit }\n");
 
34
}
 
35
 
 
36
static int vxlan_parse_opt(struct link_util *lu, int argc, char **argv,
 
37
                          struct nlmsghdr *n)
 
38
{
 
39
        __u32 vni = 0;
 
40
        int vni_set = 0;
 
41
        __u32 saddr = 0;
 
42
        __u32 gaddr = 0;
 
43
        unsigned link = 0;
 
44
        __u8 tos = 0;
 
45
        __u8 ttl = 0;
 
46
        __u8 learning = 1;
 
47
        __u8 noage = 0;
 
48
        __u32 age = 0;
 
49
        __u32 maxaddr = 0;
 
50
        struct ifla_vxlan_port_range range = { 0, 0 };
 
51
 
 
52
        while (argc > 0) {
 
53
                if (!matches(*argv, "id") ||
 
54
                    !matches(*argv, "vni")) {
 
55
                        NEXT_ARG();
 
56
                        if (get_u32(&vni, *argv, 0) ||
 
57
                            vni >= 1u << 24)
 
58
                                invarg("invalid id", *argv);
 
59
                        vni_set = 1;
 
60
                } else if (!matches(*argv, "group")) {
 
61
                        NEXT_ARG();
 
62
                        gaddr = get_addr32(*argv);
 
63
 
 
64
                        if (!IN_MULTICAST(ntohl(gaddr)))
 
65
                                invarg("invald group address", *argv);
 
66
                } else if (!matches(*argv, "local")) {
 
67
                        NEXT_ARG();
 
68
                        if (strcmp(*argv, "any"))
 
69
                                saddr = get_addr32(*argv);
 
70
                        if (IN_MULTICAST(ntohl(saddr)))
 
71
                                invarg("invalid local address", *argv);
 
72
                } else if (!matches(*argv, "dev")) {
 
73
                        NEXT_ARG();
 
74
                        link = if_nametoindex(*argv);
 
75
                        if (link == 0)
 
76
                                exit(-1);
 
77
                } else if (!matches(*argv, "ttl") ||
 
78
                           !matches(*argv, "hoplimit")) {
 
79
                        unsigned uval;
 
80
 
 
81
                        NEXT_ARG();
 
82
                        if (strcmp(*argv, "inherit") != 0) {
 
83
                                if (get_unsigned(&uval, *argv, 0))
 
84
                                        invarg("invalid TTL", *argv);
 
85
                                if (uval > 255)
 
86
                                        invarg("TTL must be <= 255", *argv);
 
87
                                ttl = uval;
 
88
                        }
 
89
                } else if (!matches(*argv, "tos") ||
 
90
                           !matches(*argv, "dsfield")) {
 
91
                        __u32 uval;
 
92
 
 
93
                        NEXT_ARG();
 
94
                        if (strcmp(*argv, "inherit") != 0) {
 
95
                                if (rtnl_dsfield_a2n(&uval, *argv))
 
96
                                        invarg("bad TOS value", *argv);
 
97
                                tos = uval;
 
98
                        } else
 
99
                                tos = 1;
 
100
                } else if (!matches(*argv, "ageing")) {
 
101
                        NEXT_ARG();
 
102
                        if (strcmp(*argv, "none") == 0)
 
103
                                noage = 1;
 
104
                        else if (get_u32(&age, *argv, 0))
 
105
                                invarg("ageing timer", *argv);
 
106
                } else if (!matches(*argv, "maxaddress")) {
 
107
                        NEXT_ARG();
 
108
                        if (strcmp(*argv, "unlimited") == 0)
 
109
                                maxaddr = 0;
 
110
                        else if (get_u32(&maxaddr, *argv, 0))
 
111
                                invarg("max addresses", *argv);
 
112
                } else if (!matches(*argv, "port")) {
 
113
                        __u16 minport, maxport;
 
114
                        NEXT_ARG();
 
115
                        if (get_u16(&minport, *argv, 0))
 
116
                                invarg("min port", *argv);
 
117
                        NEXT_ARG();
 
118
                        if (get_u16(&maxport, *argv, 0))
 
119
                                invarg("max port", *argv);
 
120
                        range.low = htons(minport);
 
121
                        range.high = htons(maxport);
 
122
                } else if (!matches(*argv, "nolearning")) {
 
123
                        learning = 0;
 
124
                } else if (!matches(*argv, "learning")) {
 
125
                        learning = 1;
 
126
                } else if (matches(*argv, "help") == 0) {
 
127
                        explain();
 
128
                        return -1;
 
129
                } else {
 
130
                        fprintf(stderr, "vxlan: what is \"%s\"?\n", *argv);
 
131
                        explain();
 
132
                        return -1;
 
133
                }
 
134
                argc--, argv++;
 
135
        }
 
136
 
 
137
        if (!vni_set) {
 
138
                fprintf(stderr, "vxlan: missing virtual network identifier\n");
 
139
                return -1;
 
140
        }
 
141
        addattr32(n, 1024, IFLA_VXLAN_ID, vni);
 
142
        if (gaddr)
 
143
                addattr_l(n, 1024, IFLA_VXLAN_GROUP, &gaddr, 4);
 
144
        if (saddr)
 
145
                addattr_l(n, 1024, IFLA_VXLAN_LOCAL, &saddr, 4);
 
146
        if (link)
 
147
                addattr32(n, 1024, IFLA_VXLAN_LINK, link);
 
148
        addattr8(n, 1024, IFLA_VXLAN_TTL, ttl);
 
149
        addattr8(n, 1024, IFLA_VXLAN_TOS, tos);
 
150
        addattr8(n, 1024, IFLA_VXLAN_LEARNING, learning);
 
151
        if (noage)
 
152
                addattr32(n, 1024, IFLA_VXLAN_AGEING, 0);
 
153
        else if (age)
 
154
                addattr32(n, 1024, IFLA_VXLAN_AGEING, age);
 
155
        if (maxaddr)
 
156
                addattr32(n, 1024, IFLA_VXLAN_LIMIT, maxaddr);
 
157
        if (range.low || range.high)
 
158
                addattr_l(n, 1024, IFLA_VXLAN_PORT_RANGE,
 
159
                          &range, sizeof(range));
 
160
 
 
161
        return 0;
 
162
}
 
163
 
 
164
static void vxlan_print_opt(struct link_util *lu, FILE *f, struct rtattr *tb[])
 
165
{
 
166
        __u32 vni;
 
167
        unsigned link;
 
168
        __u8 tos;
 
169
        __u32 maxaddr;
 
170
        char s1[1024];
 
171
        char s2[64];
 
172
 
 
173
        if (!tb)
 
174
                return;
 
175
 
 
176
        if (!tb[IFLA_VXLAN_ID] ||
 
177
            RTA_PAYLOAD(tb[IFLA_VXLAN_ID]) < sizeof(__u32))
 
178
                return;
 
179
 
 
180
        vni = rta_getattr_u32(tb[IFLA_VXLAN_ID]);
 
181
        fprintf(f, "id %u ", vni);
 
182
 
 
183
        if (tb[IFLA_VXLAN_GROUP]) {
 
184
                __be32 addr = rta_getattr_u32(tb[IFLA_VXLAN_GROUP]);
 
185
                if (addr)
 
186
                        fprintf(f, "group %s ",
 
187
                                format_host(AF_INET, 4, &addr, s1, sizeof(s1)));
 
188
        }
 
189
 
 
190
        if (tb[IFLA_VXLAN_LOCAL]) {
 
191
                __be32 addr = rta_getattr_u32(tb[IFLA_VXLAN_LOCAL]);
 
192
                if (addr)
 
193
                        fprintf(f, "local %s ", 
 
194
                                format_host(AF_INET, 4, &addr, s1, sizeof(s1)));
 
195
        }
 
196
 
 
197
        if (tb[IFLA_VXLAN_LINK] &&
 
198
            (link = rta_getattr_u32(tb[IFLA_VXLAN_LINK]))) {
 
199
                const char *n = if_indextoname(link, s2);
 
200
 
 
201
                if (n)
 
202
                        fprintf(f, "dev %s ", n);
 
203
                else
 
204
                        fprintf(f, "dev %u ", link);
 
205
        }
 
206
 
 
207
        if (tb[IFLA_VXLAN_PORT_RANGE]) {
 
208
                const struct ifla_vxlan_port_range *r
 
209
                        = RTA_DATA(tb[IFLA_VXLAN_PORT_RANGE]);
 
210
                fprintf(f, "port %u %u ", ntohs(r->low), ntohs(r->high));
 
211
        }       
 
212
 
 
213
        if (tb[IFLA_VXLAN_LEARNING] &&
 
214
            !rta_getattr_u8(tb[IFLA_VXLAN_LEARNING]))
 
215
                fputs("nolearning ", f);
 
216
        
 
217
        if (tb[IFLA_VXLAN_TOS] &&
 
218
            (tos = rta_getattr_u8(tb[IFLA_VXLAN_TOS]))) {
 
219
                if (tos == 1)
 
220
                        fprintf(f, "tos inherit ");
 
221
                else
 
222
                        fprintf(f, "tos %#x ", tos);
 
223
        }
 
224
 
 
225
        if (tb[IFLA_VXLAN_TTL]) {
 
226
                __u8 ttl = rta_getattr_u8(tb[IFLA_VXLAN_TTL]);
 
227
                if (ttl)
 
228
                        fprintf(f, "ttl %d ", ttl);
 
229
        }
 
230
 
 
231
        if (tb[IFLA_VXLAN_AGEING]) {
 
232
                __u32 age = rta_getattr_u32(tb[IFLA_VXLAN_AGEING]);
 
233
                if (age == 0)
 
234
                        fprintf(f, "ageing none ");
 
235
                else
 
236
                        fprintf(f, "ageing %u ", age);
 
237
        }
 
238
 
 
239
        if (tb[IFLA_VXLAN_LIMIT] &&
 
240
            (maxaddr = rta_getattr_u32(tb[IFLA_VXLAN_LIMIT]) != 0))
 
241
                    fprintf(f, "maxaddr %u ", maxaddr);
 
242
}
 
243
 
 
244
struct link_util vxlan_link_util = {
 
245
        .id             = "vxlan",
 
246
        .maxattr        = IFLA_VXLAN_MAX,
 
247
        .parse_opt      = vxlan_parse_opt,
 
248
        .print_opt      = vxlan_print_opt,
 
249
};