chiark / gitweb /
Add DEPLOYMENT to hostnamectl
[elogind.git] / src / network / networkd-bond.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  Tom Gundersen <teg@jklm.no>
7     Copyright 2014  Susant Sahani
8
9     systemd is free software; you can redistribute it and/or modify it
10     under the terms of the GNU Lesser General Public License as published by
11     the Free Software Foundation; either version 2.1 of the License, or
12     (at your option) any later version.
13
14     systemd is distributed in the hope that it will be useful, but
15     WITHOUT ANY WARRANTY; without even the implied warranty of
16     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17     Lesser General Public License for more details.
18
19     You should have received a copy of the GNU Lesser General Public License
20     along with systemd; If not, see <http://www.gnu.org/licenses/>.
21 ***/
22
23 #include <netinet/ether.h>
24 #include <arpa/inet.h>
25 #include <net/if.h>
26
27 #include "conf-parser.h"
28 #include "sd-rtnl.h"
29 #include "networkd.h"
30 #include "missing.h"
31
32 static const char* const bond_mode_table[_NETDEV_BOND_MODE_MAX] = {
33         [NETDEV_BOND_MODE_BALANCE_RR] = "balance-rr",
34         [NETDEV_BOND_MODE_ACTIVE_BACKUP] = "active-backup",
35         [NETDEV_BOND_MODE_BALANCE_XOR] = "balance-xor",
36         [NETDEV_BOND_MODE_BROADCAST] = "broadcast",
37         [NETDEV_BOND_MODE_802_3AD] = "802.3ad",
38         [NETDEV_BOND_MODE_BALANCE_TLB] = "balance-tlb",
39         [NETDEV_BOND_MODE_BALANCE_ALB] = "balance-alb",
40 };
41
42 DEFINE_STRING_TABLE_LOOKUP(bond_mode, BondMode);
43 DEFINE_CONFIG_PARSE_ENUM(config_parse_bond_mode, bond_mode, BondMode, "Failed to parse bond mode");
44
45 static int netdev_fill_bond_rtnl_message(NetDev *netdev, sd_rtnl_message *m) {
46         int r;
47
48         assert(m);
49
50         r = sd_rtnl_message_append_string(m, IFLA_IFNAME, netdev->ifname);
51         if (r < 0) {
52                 log_error_netdev(netdev,
53                                  "Could not append IFLA_IFNAME, attribute: %s",
54                                  strerror(-r));
55                 return r;
56         }
57
58         r = sd_rtnl_message_open_container(m, IFLA_LINKINFO);
59         if (r < 0) {
60                 log_error_netdev(netdev,
61                                  "Could not append IFLA_LINKINFO attribute: %s",
62                                  strerror(-r));
63                 return r;
64         }
65
66         r = sd_rtnl_message_open_container_union(m, IFLA_INFO_DATA,
67                                                  netdev_kind_to_string(netdev->kind));
68         if (r < 0) {
69                 log_error_netdev(netdev,
70                                  "Could not append IFLA_INFO_DATA attribute: %s",
71                                  strerror(-r));
72                 return r;
73         }
74
75         if (netdev->bond_mode != _NETDEV_BOND_MODE_INVALID) {
76                 r = sd_rtnl_message_append_u8(m, IFLA_BOND_MODE, netdev->bond_mode);
77                 if (r < 0) {
78                         log_error_netdev(netdev,
79                                          "Could not append IFLA_BOND_MODE attribute: %s",
80                                          strerror(-r));
81                         return r;
82                 }
83         }
84
85         r = sd_rtnl_message_close_container(m);
86         if (r < 0) {
87                 log_error_netdev(netdev,
88                                  "Could not append IFLA_LINKINFO attribute: %s",
89                                  strerror(-r));
90                 return r;
91         }
92
93         r = sd_rtnl_message_close_container(m);
94         if (r < 0) {
95                 log_error_netdev(netdev,
96                                  "Could not append IFLA_LINKINFO attribute: %s",
97                                  strerror(-r));
98                 return r;
99         }
100
101         return r;
102 }
103
104 int netdev_create_bond(NetDev *netdev, sd_rtnl_message_handler_t callback) {
105         _cleanup_rtnl_message_unref_ sd_rtnl_message *m = NULL;
106         int r;
107
108         assert(netdev);
109         assert(netdev->kind == NETDEV_KIND_BOND);
110         assert(netdev->ifname);
111         assert(netdev->manager);
112         assert(netdev->manager->rtnl);
113
114         r = sd_rtnl_message_new_link(netdev->manager->rtnl, &m, RTM_NEWLINK, 0);
115         if (r < 0) {
116                 log_error_netdev(netdev,
117                                  "Could not allocate RTM_NEWLINK message: %s",
118                                  strerror(-r));
119                 return r;
120         }
121
122         r = netdev_fill_bond_rtnl_message(netdev, m);
123         if(r < 0)
124                 return r;
125
126         r = sd_rtnl_call_async(netdev->manager->rtnl, m, callback, netdev, 0, NULL);
127         if (r < 0) {
128                 log_error_netdev(netdev,
129                                  "Could not send rtnetlink message: %s", strerror(-r));
130                 return r;
131         }
132
133         netdev_ref(netdev);
134
135         log_debug_netdev(netdev, "Creating bond netdev: %s",
136                          netdev_kind_to_string(netdev->kind));
137
138         netdev->state = NETDEV_STATE_CREATING;
139
140         return 0;
141 }