chiark / gitweb /
4a3a51104f1a7ec79e995b81bf0542f9ca19d8e6
[elogind.git] / src / network / networkd-netdev-vxlan.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4     This file is part of systemd.
5
6     Copyright 2014 Susant Sahani <susant@redhat.com>
7
8     systemd is free software; you can redistribute it and/or modify it
9     under the terms of the GNU Lesser General Public License as published by
10     the Free Software Foundation; either version 2.1 of the License, or
11     (at your option) any later version.
12
13     systemd is distributed in the hope that it will be useful, but
14     WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16     Lesser General Public License for more details.
17
18     You should have received a copy of the GNU Lesser General Public License
19     along with systemd; If not, see <http://www.gnu.org/licenses/>.
20 ***/
21
22 #include <net/if.h>
23
24 #include "sd-rtnl.h"
25 #include "networkd-netdev-vxlan.h"
26 #include "networkd-link.h"
27 #include "conf-parser.h"
28 #include "missing.h"
29
30 static int netdev_vxlan_fill_message_create(NetDev *netdev, Link *link, sd_rtnl_message *m) {
31         VxLan *v = VXLAN(netdev);
32         int r;
33
34         assert(netdev);
35         assert(v);
36         assert(link);
37         assert(m);
38
39
40         if (v->id <= VXLAN_VID_MAX) {
41                 r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_ID, v->id);
42                 if (r < 0) {
43                         log_netdev_error(netdev,
44                                          "Could not append IFLA_VXLAN_ID attribute: %s",
45                                          strerror(-r));
46                         return r;
47                 }
48         }
49
50         r = sd_rtnl_message_append_in_addr(m, IFLA_VXLAN_GROUP, &v->group.in);
51         if (r < 0) {
52                 log_netdev_error(netdev,
53                                  "Could not append IFLA_VXLAN_GROUP attribute: %s",
54                                  strerror(-r));
55                 return r;
56         }
57
58         r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_LINK, link->ifindex);
59         if (r < 0) {
60                 log_netdev_error(netdev,
61                                  "Could not append IFLA_VXLAN_LINK attribute: %s",
62                                  strerror(-r));
63                 return r;
64         }
65
66         if(v->ttl) {
67                 r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TTL, v->ttl);
68                 if (r < 0) {
69                         log_netdev_error(netdev,
70                                          "Could not append IFLA_VXLAN_TTL attribute: %s",
71                                          strerror(-r));
72                         return r;
73                 }
74         }
75
76         if(v->tos) {
77                 r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_TOS, v->tos);
78                 if (r < 0) {
79                         log_netdev_error(netdev,
80                                          "Could not append IFLA_VXLAN_TOS attribute: %s",
81                                          strerror(-r));
82                         return r;
83                 }
84         }
85
86         r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_LEARNING, v->learning);
87         if (r < 0) {
88                 log_netdev_error(netdev,
89                                  "Could not append IFLA_VXLAN_LEARNING attribute: %s",
90                                  strerror(-r));
91                 return r;
92         }
93
94         r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_RSC, v->route_short_circuit);
95         if (r < 0) {
96                 log_netdev_error(netdev,
97                                  "Could not append IFLA_VXLAN_RSC attribute: %s",
98                                  strerror(-r));
99                 return r;
100         }
101
102         r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_PROXY, v->arp_proxy);
103         if (r < 0) {
104                 log_netdev_error(netdev,
105                                  "Could not append IFLA_VXLAN_PROXY attribute: %s",
106                                  strerror(-r));
107                 return r;
108         }
109
110         r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L2MISS, v->l2miss);
111         if (r < 0) {
112                 log_netdev_error(netdev,
113                                  "Could not append IFLA_VXLAN_L2MISS attribute: %s",
114                                  strerror(-r));
115                 return r;
116         }
117
118         r = sd_rtnl_message_append_u8(m, IFLA_VXLAN_L3MISS, v->l3miss);
119         if (r < 0) {
120                 log_netdev_error(netdev,
121                                  "Could not append IFLA_VXLAN_L3MISS attribute: %s",
122                                  strerror(-r));
123                 return r;
124         }
125
126         if(v->fdb_ageing) {
127                 r = sd_rtnl_message_append_u32(m, IFLA_VXLAN_AGEING, v->fdb_ageing / USEC_PER_SEC);
128                 if (r < 0) {
129                         log_netdev_error(netdev,
130                                          "Could not append IFLA_VXLAN_AGEING attribute: %s",
131                                          strerror(-r));
132                         return r;
133                 }
134         }
135
136         return r;
137 }
138
139 int config_parse_vxlan_group_address(const char *unit,
140                                      const char *filename,
141                                      unsigned line,
142                                      const char *section,
143                                      unsigned section_line,
144                                      const char *lvalue,
145                                      int ltype,
146                                      const char *rvalue,
147                                      void *data,
148                                      void *userdata) {
149         VxLan *v = userdata;
150         union in_addr_union *addr = data, buffer;
151         int r, f;
152
153         assert(filename);
154         assert(lvalue);
155         assert(rvalue);
156         assert(data);
157
158         r = in_addr_from_string_auto(rvalue, &f, &buffer);
159         if (r < 0) {
160                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
161                            "vxlan multicast group address is invalid, ignoring assignment: %s", rvalue);
162                 return 0;
163         }
164
165         if(v->family != AF_UNSPEC && v->family != f) {
166                 log_syntax(unit, LOG_ERR, filename, line, EINVAL,
167                            "vxlan multicast group incompatible, ignoring assignment: %s", rvalue);
168                 return 0;
169         }
170
171         v->family = f;
172         *addr = buffer;
173
174         return 0;
175 }
176
177 static int netdev_vxlan_verify(NetDev *netdev, const char *filename) {
178         VxLan *v = VXLAN(netdev);
179
180         assert(netdev);
181         assert(v);
182         assert(filename);
183
184         if (v->id > VXLAN_VID_MAX) {
185                 log_warning("VXLAN without valid Id configured in %s. Ignoring", filename);
186                 return -EINVAL;
187         }
188
189         return 0;
190 }
191
192 static void vxlan_init(NetDev *netdev) {
193         VxLan *v = VXLAN(netdev);
194
195         assert(netdev);
196         assert(v);
197
198         v->id = VXLAN_VID_MAX + 1;
199         v->learning = true;
200 }
201
202 const NetDevVTable vxlan_vtable = {
203         .object_size = sizeof(VxLan),
204         .init = vxlan_init,
205         .sections = "Match\0NetDev\0VXLAN\0",
206         .fill_message_create = netdev_vxlan_fill_message_create,
207         .create_type = NETDEV_CREATE_STACKED,
208         .config_verify = netdev_vxlan_verify,
209 };