Line data Source code
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 : #include <linux/veth.h>
24 :
25 : #include "sd-netlink.h"
26 : #include "networkd-netdev-veth.h"
27 :
28 0 : static int netdev_veth_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) {
29 0 : Veth *v = VETH(netdev);
30 : int r;
31 :
32 0 : assert(netdev);
33 0 : assert(!link);
34 0 : assert(v);
35 0 : assert(m);
36 :
37 0 : r = sd_netlink_message_open_container(m, VETH_INFO_PEER);
38 0 : if (r < 0)
39 0 : return log_netdev_error_errno(netdev, r, "Could not append VETH_INFO_PEER attribute: %m");
40 :
41 0 : if (v->ifname_peer) {
42 0 : r = sd_netlink_message_append_string(m, IFLA_IFNAME, v->ifname_peer);
43 0 : if (r < 0)
44 0 : return log_error_errno(r, "Failed to add netlink interface name: %m");
45 : }
46 :
47 0 : if (v->mac_peer) {
48 0 : r = sd_netlink_message_append_ether_addr(m, IFLA_ADDRESS, v->mac_peer);
49 0 : if (r < 0)
50 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_ADDRESS attribute: %m");
51 : }
52 :
53 0 : r = sd_netlink_message_close_container(m);
54 0 : if (r < 0)
55 0 : return log_netdev_error_errno(netdev, r, "Could not append IFLA_INFO_DATA attribute: %m");
56 :
57 0 : return r;
58 : }
59 :
60 0 : static int netdev_veth_verify(NetDev *netdev, const char *filename) {
61 0 : Veth *v = VETH(netdev);
62 : int r;
63 :
64 0 : assert(netdev);
65 0 : assert(v);
66 0 : assert(filename);
67 :
68 0 : if (!v->ifname_peer) {
69 0 : log_warning("Veth NetDev without peer name configured in %s. Ignoring",
70 : filename);
71 0 : return -EINVAL;
72 : }
73 :
74 0 : if (!v->mac_peer) {
75 0 : r = netdev_get_mac(v->ifname_peer, &v->mac_peer);
76 0 : if (r < 0) {
77 0 : log_warning("Failed to generate predictable MAC address for %s. Ignoring",
78 : v->ifname_peer);
79 0 : return -EINVAL;
80 : }
81 : }
82 :
83 0 : return 0;
84 : }
85 :
86 0 : static void veth_done(NetDev *n) {
87 0 : Veth *v = VETH(n);
88 :
89 0 : assert(n);
90 0 : assert(v);
91 :
92 0 : free(v->ifname_peer);
93 0 : free(v->mac_peer);
94 0 : }
95 :
96 : const NetDevVTable veth_vtable = {
97 : .object_size = sizeof(Veth),
98 : .sections = "Match\0NetDev\0Peer\0",
99 : .done = veth_done,
100 : .fill_message_create = netdev_veth_fill_message_create,
101 : .create_type = NETDEV_CREATE_INDEPENDENT,
102 : .config_verify = netdev_veth_verify,
103 : };
|