Skip to content
GitLab
Explore
Sign in
Register
Primary navigation
Search or go to…
Project
F
ffbs-gluon
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
darkbit
ffbs-gluon
Commits
249ff340
Unverified
Commit
249ff340
authored
8 years ago
by
Matthias Schiffer
Browse files
Options
Downloads
Patches
Plain Diff
netifd: device: add veth support
parent
57f8b9bc
No related branches found
No related tags found
No related merge requests found
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
patches/lede/0011-netifd-device-add-veth-support.patch
+447
-0
447 additions, 0 deletions
patches/lede/0011-netifd-device-add-veth-support.patch
with
447 additions
and
0 deletions
patches/lede/0011-netifd-device-add-veth-support.patch
0 → 100644
+
447
−
0
View file @
249ff340
From: Matthias Schiffer <mschiffer@universe-factory.net>
Date: Fri, 10 Feb 2017 06:33:03 +0100
Subject: netifd: device: add veth support
diff --git a/package/network/config/netifd/patches/0001-device-add-veth-support.patch b/package/network/config/netifd/patches/0001-device-add-veth-support.patch
new file mode 100644
index 0000000000000000000000000000000000000000..9fdc184e98c070d0636fda5c6e5716295b86ecba
--- /dev/null
+++ b/package/network/config/netifd/patches/0001-device-add-veth-support.patch
@@ -0,0 +1,437 @@
+From 006a6d3084cfd034f7d66cde3a0cbf58ab34c5a7 Mon Sep 17 00:00:00 2001
+Message-Id: <006a6d3084cfd034f7d66cde3a0cbf58ab34c5a7.1486704740.git.mschiffer@universe-factory.net>
+From: Matthias Schiffer <mschiffer@universe-factory.net>
+Date: Fri, 10 Feb 2017 04:29:09 +0100
+Subject: [PATCH] device: add veth support
+
+The veth config code mostly handles the primary interface of a veth pair,
+the secondary interface is not explicitly referenced and will be found as
+an unrelated interface after the pair has been created.
+
+This doesn't only allow us to keep the veth code simple (and similar to
+existing device handlers), but will also avoid complicating handling
+unnecessarily in case the secondary interface is moved into another network
+namespace.
+
+Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
+---
+ CMakeLists.txt | 2 +-
+ system-dummy.c | 10 +++
+ system-linux.c | 61 ++++++++++++++
+ system.h | 18 +++++
+ veth.c | 247 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+ 5 files changed, 337 insertions(+), 1 deletion(-)
+ create mode 100644 veth.c
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 1f35d26..d54b6fa 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -9,7 +9,7 @@ SET(SOURCES
+ main.c utils.c system.c tunnel.c handler.c
+ interface.c interface-ip.c interface-event.c
+ iprule.c proto.c proto-static.c proto-shell.c
+- config.c device.c bridge.c vlan.c alias.c
++ config.c device.c bridge.c veth.c vlan.c alias.c
+ macvlan.c ubus.c vlandev.c wireless.c)
+
+
+diff --git a/system-dummy.c b/system-dummy.c
+index 9c734ea..2dd27c7 100644
+--- a/system-dummy.c
++++ b/system-dummy.c
+@@ -275,6 +275,16 @@ int system_macvlan_del(struct device *macvlan)
+ return 0;
+ }
+
++int system_veth_add(struct device *veth, struct veth_config *cfg)
++{
++ return 0;
++}
++
++int system_veth_del(struct device *veth)
++{
++ return 0;
++}
++
+ int system_vlandev_add(struct device *vlandev, struct device *dev, struct vlandev_config *cfg)
+ {
+ return 0;
+diff --git a/system-linux.c b/system-linux.c
+index 2f15bf1..73e841b 100644
+--- a/system-linux.c
++++ b/system-linux.c
+@@ -38,6 +38,7 @@
+ #include <linux/ip6_tunnel.h>
+ #include <linux/ethtool.h>
+ #include <linux/fib_rules.h>
++#include <linux/veth.h>
+ #include <linux/version.h>
+
+ #ifndef RTN_FAILED_POLICY
+@@ -1132,6 +1133,66 @@ int system_macvlan_del(struct device *macvlan)
+ return system_link_del(macvlan->ifname);
+ }
+
++int system_veth_add(struct device *veth, struct veth_config *cfg)
++{
++ struct nl_msg *msg;
++ struct ifinfomsg empty_iim = {};
++ struct nlattr *linkinfo, *data, *veth_info;
++ int rv;
++
++ msg = nlmsg_alloc_simple(RTM_NEWLINK, NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL);
++
++ if (!msg)
++ return -1;
++
++ nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
++
++ if (cfg->flags & VETH_OPT_MACADDR)
++ nla_put(msg, IFLA_ADDRESS, sizeof(cfg->macaddr), cfg->macaddr);
++ nla_put_string(msg, IFLA_IFNAME, veth->ifname);
++
++ if (!(linkinfo = nla_nest_start(msg, IFLA_LINKINFO)))
++ goto nla_put_failure;
++
++ nla_put_string(msg, IFLA_INFO_KIND, "veth");
++
++ if (!(data = nla_nest_start(msg, IFLA_INFO_DATA)))
++ goto nla_put_failure;
++
++ if (!(veth_info = nla_nest_start(msg, VETH_INFO_PEER)))
++ goto nla_put_failure;
++
++ nlmsg_append(msg, &empty_iim, sizeof(empty_iim), 0);
++
++ if (cfg->flags & VETH_OPT_PEER_NAME)
++ nla_put_string(msg, IFLA_IFNAME, cfg->peer_name);
++ if (cfg->flags & VETH_OPT_PEER_MACADDR)
++ nla_put(msg, IFLA_ADDRESS, sizeof(cfg->peer_macaddr), cfg->peer_macaddr);
++
++ nla_nest_end(msg, veth_info);
++ nla_nest_end(msg, data);
++ nla_nest_end(msg, linkinfo);
++
++ rv = system_rtnl_call(msg);
++ if (rv) {
++ if (cfg->flags & VETH_OPT_PEER_NAME)
++ D(SYSTEM, "Error adding veth '%s' with peer '%s': %d\n", veth->ifname, cfg->peer_name, rv);
++ else
++ D(SYSTEM, "Error adding veth '%s': %d\n", veth->ifname, rv);
++ }
++
++ return rv;
++
++nla_put_failure:
++ nlmsg_free(msg);
++ return -ENOMEM;
++}
++
++int system_veth_del(struct device *veth)
++{
++ return system_link_del(veth->ifname);
++}
++
+ static int system_vlan(struct device *dev, int id)
+ {
+ struct vlan_ioctl_args ifr = {
+diff --git a/system.h b/system.h
+index d5cb4e3..f4dd02b 100644
+--- a/system.h
++++ b/system.h
+@@ -14,6 +14,7 @@
+ #ifndef __NETIFD_SYSTEM_H
+ #define __NETIFD_SYSTEM_H
+
++#include <net/if.h>
+ #include <sys/time.h>
+ #include <sys/socket.h>
+ #include <arpa/inet.h>
+@@ -82,6 +83,20 @@ struct macvlan_config {
+ unsigned char macaddr[6];
+ };
+
++enum veth_opt {
++ VETH_OPT_MACADDR = (1 << 0),
++ VETH_OPT_PEER_NAME = (1 << 1),
++ VETH_OPT_PEER_MACADDR = (1 << 2),
++};
++
++struct veth_config {
++ enum veth_opt flags;
++
++ unsigned char macaddr[6];
++ char peer_name[IFNAMSIZ];
++ unsigned char peer_macaddr[6];
++};
++
+ enum vlan_proto {
+ VLAN_PROTO_8021Q = 0x8100,
+ VLAN_PROTO_8021AD = 0x88A8
+@@ -118,6 +133,9 @@ int system_bridge_delif(struct device *bridge, struct device *dev);
+ int system_macvlan_add(struct device *macvlan, struct device *dev, struct macvlan_config *cfg);
+ int system_macvlan_del(struct device *macvlan);
+
++int system_veth_add(struct device *veth, struct veth_config *cfg);
++int system_veth_del(struct device *veth);
++
+ int system_vlan_add(struct device *dev, int id);
+ int system_vlan_del(struct device *dev);
+
+diff --git a/veth.c b/veth.c
+new file mode 100644
+index 0000000..e109f27
+--- /dev/null
++++ b/veth.c
+@@ -0,0 +1,247 @@
++/*
++ * netifd - network interface daemon
++ * Copyright (C) 2012 Felix Fietkau <nbd@openwrt.org>
++ * Copyright (C) 2013 Jo-Philipp Wich <jow@openwrt.org>
++ * Copyright (C) 2017 Matthias Schiffer <mschiffer@universe-factory.net>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License version 2
++ * as published by the Free Software Foundation
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++#include <string.h>
++#include <stdlib.h>
++#include <stdio.h>
++#include <assert.h>
++#include <errno.h>
++#include <net/ethernet.h>
++
++#ifdef linux
++#include <netinet/ether.h>
++#endif
++
++#include "netifd.h"
++#include "device.h"
++#include "interface.h"
++#include "system.h"
++
++enum {
++ VETH_ATTR_MACADDR,
++ VETH_ATTR_PEER_NAME,
++ VETH_ATTR_PEER_MACADDR,
++ __VETH_ATTR_MAX
++};
++
++static const struct blobmsg_policy veth_attrs[__VETH_ATTR_MAX] = {
++ [VETH_ATTR_MACADDR] = { "macaddr", BLOBMSG_TYPE_STRING },
++ [VETH_ATTR_PEER_NAME] = { "peer_name", BLOBMSG_TYPE_STRING },
++ [VETH_ATTR_PEER_MACADDR] = { "peer_macaddr", BLOBMSG_TYPE_STRING },
++};
++
++static const struct uci_blob_param_list veth_attr_list = {
++ .n_params = __VETH_ATTR_MAX,
++ .params = veth_attrs,
++
++ .n_next = 1,
++ .next = { &device_attr_list },
++};
++
++struct veth {
++ struct device dev;
++
++ device_state_cb set_state;
++
++ struct blob_attr *config_data;
++ struct veth_config config;
++};
++
++static int
++veth_set_down(struct veth *veth)
++{
++ veth->set_state(&veth->dev, false);
++ system_veth_del(&veth->dev);
++
++ return 0;
++}
++
++static int
++veth_set_up(struct veth *veth)
++{
++ int ret;
++
++ ret = system_veth_add(&veth->dev, &veth->config);
++ if (ret < 0)
++ return ret;
++
++ ret = veth->set_state(&veth->dev, true);
++ if (ret)
++ goto delete;
++
++ return 0;
++
++delete:
++ system_veth_del(&veth->dev);
++ return ret;
++}
++
++static int
++veth_set_state(struct device *dev, bool up)
++{
++ struct veth *veth;
++
++ D(SYSTEM, "veth_set_state(%s, %u)\n", dev->ifname, up);
++
++ veth = container_of(dev, struct veth, dev);
++ if (up)
++ return veth_set_up(veth);
++ else
++ return veth_set_down(veth);
++}
++
++static void
++veth_free(struct device *dev)
++{
++ struct veth *veth;
++
++ veth = container_of(dev, struct veth, dev);
++ free(veth->config_data);
++ free(veth);
++}
++
++static void
++veth_dump_info(struct device *dev, struct blob_buf *b)
++{
++ struct veth *veth;
++
++ veth = container_of(dev, struct veth, dev);
++ if (veth->config.flags & VETH_OPT_PEER_NAME)
++ blobmsg_add_string(b, "peer", veth->config.peer_name);
++ system_if_dump_info(dev, b);
++}
++
++static void
++veth_config_init(struct device *dev)
++{
++ device_set_present(dev, true);
++}
++
++static void
++veth_apply_settings(struct veth *veth, struct blob_attr **tb)
++{
++ struct veth_config *cfg = &veth->config;
++ struct blob_attr *cur;
++ struct ether_addr *ea;
++
++ cfg->flags = 0;
++
++ if ((cur = tb[VETH_ATTR_MACADDR]))
++ {
++ ea = ether_aton(blobmsg_data(cur));
++ if (ea) {
++ memcpy(cfg->macaddr, ea, 6);
++ cfg->flags |= VETH_OPT_MACADDR;
++ }
++ }
++
++ if ((cur = tb[VETH_ATTR_PEER_NAME]))
++ {
++ strncpy(cfg->peer_name, blobmsg_get_string(cur), sizeof(cfg->peer_name)-1);
++ cfg->flags |= VETH_OPT_PEER_NAME;
++ }
++
++ if ((cur = tb[VETH_ATTR_PEER_MACADDR]))
++ {
++ ea = ether_aton(blobmsg_data(cur));
++ if (ea) {
++ memcpy(cfg->peer_macaddr, ea, 6);
++ cfg->flags |= VETH_OPT_PEER_MACADDR;
++ }
++ }
++}
++
++static enum dev_change_type
++veth_reload(struct device *dev, struct blob_attr *attr)
++{
++ struct blob_attr *tb_dev[__DEV_ATTR_MAX];
++ struct blob_attr *tb_mv[__VETH_ATTR_MAX];
++ enum dev_change_type ret = DEV_CONFIG_APPLIED;
++ struct veth *veth;
++
++ veth = container_of(dev, struct veth, dev);
++ attr = blob_memdup(attr);
++
++ blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, tb_dev,
++ blob_data(attr), blob_len(attr));
++ blobmsg_parse(veth_attrs, __VETH_ATTR_MAX, tb_mv,
++ blob_data(attr), blob_len(attr));
++
++ device_init_settings(dev, tb_dev);
++ veth_apply_settings(veth, tb_mv);
++
++ if (veth->config_data) {
++ struct blob_attr *otb_dev[__DEV_ATTR_MAX];
++ struct blob_attr *otb_mv[__VETH_ATTR_MAX];
++
++ blobmsg_parse(device_attr_list.params, __DEV_ATTR_MAX, otb_dev,
++ blob_data(veth->config_data), blob_len(veth->config_data));
++
++ if (uci_blob_diff(tb_dev, otb_dev, &device_attr_list, NULL))
++ ret = DEV_CONFIG_RESTART;
++
++ blobmsg_parse(veth_attrs, __VETH_ATTR_MAX, otb_mv,
++ blob_data(veth->config_data), blob_len(veth->config_data));
++
++ if (uci_blob_diff(tb_mv, otb_mv, &veth_attr_list, NULL))
++ ret = DEV_CONFIG_RESTART;
++
++ veth_config_init(dev);
++ }
++
++ free(veth->config_data);
++ veth->config_data = attr;
++ return ret;
++}
++
++static struct device *
++veth_create(const char *name, struct device_type *devtype,
++ struct blob_attr *attr)
++{
++ struct veth *veth;
++ struct device *dev = NULL;
++
++ veth = calloc(1, sizeof(*veth));
++ if (!veth)
++ return NULL;
++
++ dev = &veth->dev;
++ device_init(dev, devtype, name);
++ dev->config_pending = true;
++
++ veth->set_state = dev->set_state;
++ dev->set_state = veth_set_state;
++
++ dev->hotplug_ops = NULL;
++
++ veth_reload(dev, attr);
++
++ return dev;
++}
++
++static struct device_type veth_device_type = {
++ .name = "veth",
++ .config_params = &veth_attr_list,
++ .create = veth_create,
++ .config_init = veth_config_init,
++ .reload = veth_reload,
++ .free = veth_free,
++ .dump_info = veth_dump_info,
++};
++
++static void __init veth_device_type_init(void)
++{
++ device_type_add(&veth_device_type);
++}
+--
+2.11.1
+
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment