• source navigation  • diff markup  • identifier search  • freetext search  • 

Sources/netifd/veth.c

  1 /*
  2  * netifd - network interface daemon
  3  * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
  4  * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
  5  * Copyright (C) 2017 Matthias Schiffer <mschiffer@universe-factory.net>
  6  *
  7  * This program is free software; you can redistribute it and/or modify
  8  * it under the terms of the GNU General Public License version 2
  9  * as published by the Free Software Foundation
 10  *
 11  * This program is distributed in the hope that it will be useful,
 12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 14  * GNU General Public License for more details.
 15  */
 16 #include <string.h>
 17 #include <stdlib.h>
 18 #include <stdio.h>
 19 #include <assert.h>
 20 #include <errno.h>
 21 #include <net/ethernet.h>
 22 
 23 #ifdef linux
 24 #include <netinet/ether.h>
 25 #endif
 26 
 27 #include "netifd.h"
 28 #include "device.h"
 29 #include "interface.h"
 30 #include "system.h"
 31 
 32 enum {
 33         VETH_ATTR_MACADDR,
 34         VETH_ATTR_PEER_NAME,
 35         VETH_ATTR_PEER_MACADDR,
 36         __VETH_ATTR_MAX
 37 };
 38 
 39 static const struct blobmsg_policy veth_attrs[__VETH_ATTR_MAX] = {
 40         [VETH_ATTR_MACADDR] = { "macaddr", BLOBMSG_TYPE_STRING },
 41         [VETH_ATTR_PEER_NAME]  = { "peer_name", BLOBMSG_TYPE_STRING },
 42         [VETH_ATTR_PEER_MACADDR] = { "peer_macaddr", BLOBMSG_TYPE_STRING },
 43 };
 44 
 45 static const struct uci_blob_param_list veth_attr_list = {
 46         .n_params = __VETH_ATTR_MAX,
 47         .params = veth_attrs,
 48 
 49         .n_next = 1,
 50         .next = { &device_attr_list },
 51 };
 52 
 53 struct veth {
 54         struct device dev;
 55 
 56         device_state_cb set_state;
 57 
 58         struct blob_attr *config_data;
 59         struct veth_config config;
 60 };
 61 
 62 static int
 63 veth_set_down(struct veth *veth)
 64 {
 65         veth->set_state(&veth->dev, false);
 66         system_veth_del(&veth->dev);
 67 
 68         return 0;
 69 }
 70 
 71 static int
 72 veth_set_up(struct veth *veth)
 73 {
 74         int ret;
 75 
 76         ret = system_veth_add(&veth->dev, &veth->config);
 77         if (ret < 0)
 78                 return ret;
 79 
 80         ret = veth->set_state(&veth->dev, true);
 81         if (ret)
 82                 goto delete;
 83 
 84         return 0;
 85 
 86 delete:
 87         system_veth_del(&veth->dev);
 88         return ret;
 89 }
 90 
 91 static int
 92 veth_set_state(struct device *dev, bool up)
 93 {
 94         struct veth *veth;
 95 
 96         D(SYSTEM, "veth_set_state(%s, %u)\n", dev->ifname, up);
 97 
 98         veth = container_of(dev, struct veth, dev);
 99         if (up)
100                 return veth_set_up(veth);
101         else
102                 return veth_set_down(veth);
103 }
104 
105 static void
106 veth_free(struct device *dev)
107 {
108         struct veth *veth;
109 
110         veth = container_of(dev, struct veth, dev);
111         free(veth->config_data);
112         free(veth);
113 }
114 
115 static void
116 veth_dump_info(struct device *dev, struct blob_buf *b)
117 {
118         struct veth *veth;
119 
120         veth = container_of(dev, struct veth, dev);
121         if (veth->config.flags & VETH_OPT_PEER_NAME)
122                 blobmsg_add_string(b, "peer", veth->config.peer_name);
123         system_if_dump_info(dev, b);
124 }
125 
126 static void
127 veth_config_init(struct device *dev)
128 {
129         device_set_present(dev, true);
130 }
131 
132 static void
133 veth_apply_settings(struct veth *veth, struct blob_attr **tb)
134 {
135         struct veth_config *cfg = &veth->config;
136         struct blob_attr *cur;
137         struct ether_addr *ea;
138 
139         cfg->flags = 0;
140 
141         if ((cur = tb[VETH_ATTR_MACADDR]))
142         {
143                 ea = ether_aton(blobmsg_data(cur));
144                 if (ea) {
145                         memcpy(cfg->macaddr, ea, 6);
146                         cfg->flags |= VETH_OPT_MACADDR;
147                 }
148         }
149 
150         if ((cur = tb[VETH_ATTR_PEER_NAME]))
151         {
152                 strncpy(cfg->peer_name, blobmsg_get_string(cur), sizeof(cfg->peer_name)-1);
153                 cfg->flags |= VETH_OPT_PEER_NAME;
154         }
155 
156         if ((cur = tb[VETH_ATTR_PEER_MACADDR]))
157         {
158                 ea = ether_aton(blobmsg_data(cur));
159                 if (ea) {
160                         memcpy(cfg->peer_macaddr, ea, 6);
161                         cfg->flags |= VETH_OPT_PEER_MACADDR;
162                 }
163         }
164 }
165 
166 static enum dev_change_type
167 veth_reload(struct device *dev, struct blob_attr *attr)
168 {
169         struct blob_attr *tb_dev[__DEV_ATTR_MAX];
170         struct blob_attr *tb_mv[__VETH_ATTR_MAX];
171         enum dev_change_type ret = DEV_CONFIG_APPLIED;
172         struct veth *veth;
173 
174         veth = container_of(dev, struct veth, dev);
175         attr = blob_memdup(attr);
176 
177         blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev,
178                 blob_data(attr), blob_len(attr));
179         blobmsg_parse(veth_attrs, __VETH_ATTR_MAX, tb_mv,
180                 blob_data(attr), blob_len(attr));
181 
182         device_init_settings(dev, tb_dev);
183         veth_apply_settings(veth, tb_mv);
184 
185         if (veth->config_data) {
186                 struct blob_attr *otb_dev[__DEV_ATTR_MAX];
187                 struct blob_attr *otb_mv[__VETH_ATTR_MAX];
188 
189                 blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev,
190                         blob_data(veth->config_data), blob_len(veth->config_data));
191 
192                 if (uci_blob_diff(tb_dev, otb_dev, &device_attr_list, NULL))
193                     ret = DEV_CONFIG_RESTART;
194 
195                 blobmsg_parse(veth_attrs, __VETH_ATTR_MAX, otb_mv,
196                         blob_data(veth->config_data), blob_len(veth->config_data));
197 
198                 if (uci_blob_diff(tb_mv, otb_mv, &veth_attr_list, NULL))
199                     ret = DEV_CONFIG_RESTART;
200 
201                 veth_config_init(dev);
202         }
203 
204         free(veth->config_data);
205         veth->config_data = attr;
206         return ret;
207 }
208 
209 static struct device *
210 veth_create(const char *name, struct device_type *devtype,
211         struct blob_attr *attr)
212 {
213         struct veth *veth;
214         struct device *dev = NULL;
215 
216         veth = calloc(1, sizeof(*veth));
217         if (!veth)
218                 return NULL;
219 
220         dev = &veth->dev;
221         if (device_init(dev, devtype, name) < 0) {
222                 device_cleanup(dev);
223                 free(veth);
224                 return NULL;
225         }
226 
227         dev->config_pending = true;
228 
229         veth->set_state = dev->set_state;
230         dev->set_state = veth_set_state;
231 
232         dev->hotplug_ops = NULL;
233 
234         veth_reload(dev, attr);
235 
236         return dev;
237 }
238 
239 static struct device_type veth_device_type = {
240         .name = "veth",
241         .config_params = &veth_attr_list,
242         .create = veth_create,
243         .config_init = veth_config_init,
244         .reload = veth_reload,
245         .free = veth_free,
246         .dump_info = veth_dump_info,
247 };
248 
249 static void __init veth_device_type_init(void)
250 {
251         device_type_add(&veth_device_type);
252 }
253 

This page was automatically generated by LXR 0.3.1.  •  OpenWrt