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 22 #include "netifd.h" 23 #include "device.h" 24 #include "interface.h" 25 #include "system.h" 26 27 enum { 28 VETH_ATTR_MACADDR, 29 VETH_ATTR_PEER_NAME, 30 VETH_ATTR_PEER_MACADDR, 31 __VETH_ATTR_MAX 32 }; 33 34 static const struct blobmsg_policy veth_attrs[__VETH_ATTR_MAX] = { 35 [VETH_ATTR_MACADDR] = { "macaddr", BLOBMSG_TYPE_STRING }, 36 [VETH_ATTR_PEER_NAME] = { "peer_name", BLOBMSG_TYPE_STRING }, 37 [VETH_ATTR_PEER_MACADDR] = { "peer_macaddr", BLOBMSG_TYPE_STRING }, 38 }; 39 40 static const struct uci_blob_param_list veth_attr_list = { 41 .n_params = __VETH_ATTR_MAX, 42 .params = veth_attrs, 43 44 .n_next = 1, 45 .next = { &device_attr_list }, 46 }; 47 48 struct veth { 49 struct device dev; 50 51 device_state_cb set_state; 52 53 struct blob_attr *config_data; 54 struct veth_config config; 55 }; 56 57 static int 58 veth_set_down(struct veth *veth) 59 { 60 veth->set_state(&veth->dev, false); 61 system_veth_del(&veth->dev); 62 63 return 0; 64 } 65 66 static int 67 veth_set_up(struct veth *veth) 68 { 69 int ret; 70 71 system_veth_del(&veth->dev); 72 73 ret = system_veth_add(&veth->dev, &veth->config); 74 if (ret < 0) 75 return ret; 76 77 ret = veth->set_state(&veth->dev, true); 78 if (ret) 79 goto delete; 80 81 return 0; 82 83 delete: 84 system_veth_del(&veth->dev); 85 return ret; 86 } 87 88 static int 89 veth_set_state(struct device *dev, bool up) 90 { 91 struct veth *veth; 92 93 D(SYSTEM, "veth_set_state(%s, %u)", dev->ifname, up); 94 95 veth = container_of(dev, struct veth, dev); 96 if (up) 97 return veth_set_up(veth); 98 else 99 return veth_set_down(veth); 100 } 101 102 static void 103 veth_free(struct device *dev) 104 { 105 struct veth *veth; 106 107 veth = container_of(dev, struct veth, dev); 108 free(veth->config_data); 109 free(veth); 110 } 111 112 static void 113 veth_dump_info(struct device *dev, struct blob_buf *b) 114 { 115 struct veth *veth; 116 117 veth = container_of(dev, struct veth, dev); 118 if (veth->config.flags & VETH_OPT_PEER_NAME) 119 blobmsg_add_string(b, "peer", veth->config.peer_name); 120 system_if_dump_info(dev, b); 121 } 122 123 static void 124 veth_config_init(struct device *dev) 125 { 126 device_set_present(dev, true); 127 } 128 129 static void 130 veth_apply_settings(struct veth *veth, struct blob_attr **tb) 131 { 132 struct veth_config *cfg = &veth->config; 133 struct blob_attr *cur; 134 struct ether_addr *ea; 135 136 cfg->flags = 0; 137 138 if ((cur = tb[VETH_ATTR_MACADDR])) 139 { 140 ea = ether_aton(blobmsg_data(cur)); 141 if (ea) { 142 memcpy(cfg->macaddr, ea, 6); 143 cfg->flags |= VETH_OPT_MACADDR; 144 } 145 } 146 147 if ((cur = tb[VETH_ATTR_PEER_NAME])) 148 { 149 strncpy(cfg->peer_name, blobmsg_get_string(cur), sizeof(cfg->peer_name)-1); 150 cfg->flags |= VETH_OPT_PEER_NAME; 151 } 152 153 if ((cur = tb[VETH_ATTR_PEER_MACADDR])) 154 { 155 ea = ether_aton(blobmsg_data(cur)); 156 if (ea) { 157 memcpy(cfg->peer_macaddr, ea, 6); 158 cfg->flags |= VETH_OPT_PEER_MACADDR; 159 } 160 } 161 } 162 163 static enum dev_change_type 164 veth_reload(struct device *dev, struct blob_attr *attr) 165 { 166 struct blob_attr *tb_dev[__DEV_ATTR_MAX]; 167 struct blob_attr *tb_mv[__VETH_ATTR_MAX]; 168 enum dev_change_type ret = DEV_CONFIG_APPLIED; 169 struct veth *veth; 170 171 veth = container_of(dev, struct veth, dev); 172 attr = blob_memdup(attr); 173 174 blobmsg_parse_attr(device_attr_list.params, __DEV_ATTR_MAX, tb_dev, attr); 175 blobmsg_parse_attr(veth_attrs, __VETH_ATTR_MAX, tb_mv, attr); 176 177 device_init_settings(dev, tb_dev); 178 veth_apply_settings(veth, tb_mv); 179 180 if (veth->config_data) { 181 struct blob_attr *otb_dev[__DEV_ATTR_MAX]; 182 struct blob_attr *otb_mv[__VETH_ATTR_MAX]; 183 184 blobmsg_parse_attr(device_attr_list.params, __DEV_ATTR_MAX, otb_dev, 185 veth->config_data); 186 187 if (uci_blob_diff(tb_dev, otb_dev, &device_attr_list, NULL)) 188 ret = DEV_CONFIG_RESTART; 189 190 blobmsg_parse_attr(veth_attrs, __VETH_ATTR_MAX, otb_mv, 191 veth->config_data); 192 193 if (uci_blob_diff(tb_mv, otb_mv, &veth_attr_list, NULL)) 194 ret = DEV_CONFIG_RESTART; 195 196 veth_config_init(dev); 197 } 198 199 free(veth->config_data); 200 veth->config_data = attr; 201 return ret; 202 } 203 204 static struct device * 205 veth_create(const char *name, struct device_type *devtype, 206 struct blob_attr *attr) 207 { 208 struct veth *veth; 209 struct device *dev = NULL; 210 211 veth = calloc(1, sizeof(*veth)); 212 if (!veth) 213 return NULL; 214 215 dev = &veth->dev; 216 if (device_init(dev, devtype, name) < 0) { 217 device_cleanup(dev); 218 free(veth); 219 return NULL; 220 } 221 222 dev->config_pending = true; 223 224 veth->set_state = dev->set_state; 225 dev->set_state = veth_set_state; 226 227 dev->hotplug_ops = NULL; 228 229 veth_reload(dev, attr); 230 231 return dev; 232 } 233 234 static struct device_type veth_device_type = { 235 .name = "veth", 236 .config_params = &veth_attr_list, 237 .create = veth_create, 238 .config_init = veth_config_init, 239 .reload = veth_reload, 240 .free = veth_free, 241 .dump_info = veth_dump_info, 242 }; 243 244 static void __init veth_device_type_init(void) 245 { 246 device_type_add(&veth_device_type); 247 } 248
This page was automatically generated by LXR 0.3.1. • OpenWrt