1
1
/*
2
2
* drivers/net/bond/bond_netlink.c - Netlink interface for bonding
3
3
* Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
4
+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
4
5
*
5
6
* This program is free software; you can redistribute it and/or modify
6
7
* it under the terms of the GNU General Public License as published by
23
24
static const struct nla_policy bond_policy [IFLA_BOND_MAX + 1 ] = {
24
25
[IFLA_BOND_MODE ] = { .type = NLA_U8 },
25
26
[IFLA_BOND_ACTIVE_SLAVE ] = { .type = NLA_U32 },
27
+ [IFLA_BOND_MIIMON ] = { .type = NLA_U32 },
28
+ [IFLA_BOND_UPDELAY ] = { .type = NLA_U32 },
29
+ [IFLA_BOND_DOWNDELAY ] = { .type = NLA_U32 },
30
+ [IFLA_BOND_USE_CARRIER ] = { .type = NLA_U8 },
31
+ [IFLA_BOND_ARP_INTERVAL ] = { .type = NLA_U32 },
32
+ [IFLA_BOND_ARP_IP_TARGET ] = { .type = NLA_NESTED },
33
+ [IFLA_BOND_ARP_VALIDATE ] = { .type = NLA_U32 },
34
+ [IFLA_BOND_ARP_ALL_TARGETS ] = { .type = NLA_U32 },
26
35
};
27
36
28
37
static int bond_validate (struct nlattr * tb [], struct nlattr * data [])
@@ -40,16 +49,20 @@ static int bond_changelink(struct net_device *bond_dev,
40
49
struct nlattr * tb [], struct nlattr * data [])
41
50
{
42
51
struct bonding * bond = netdev_priv (bond_dev );
52
+ int miimon = 0 ;
43
53
int err ;
44
54
45
- if (data && data [IFLA_BOND_MODE ]) {
55
+ if (!data )
56
+ return 0 ;
57
+
58
+ if (data [IFLA_BOND_MODE ]) {
46
59
int mode = nla_get_u8 (data [IFLA_BOND_MODE ]);
47
60
48
61
err = bond_option_mode_set (bond , mode );
49
62
if (err )
50
63
return err ;
51
64
}
52
- if (data && data [IFLA_BOND_ACTIVE_SLAVE ]) {
65
+ if (data [IFLA_BOND_ACTIVE_SLAVE ]) {
53
66
int ifindex = nla_get_u32 (data [IFLA_BOND_ACTIVE_SLAVE ]);
54
67
struct net_device * slave_dev ;
55
68
@@ -65,6 +78,82 @@ static int bond_changelink(struct net_device *bond_dev,
65
78
if (err )
66
79
return err ;
67
80
}
81
+ if (data [IFLA_BOND_MIIMON ]) {
82
+ miimon = nla_get_u32 (data [IFLA_BOND_MIIMON ]);
83
+
84
+ err = bond_option_miimon_set (bond , miimon );
85
+ if (err )
86
+ return err ;
87
+ }
88
+ if (data [IFLA_BOND_UPDELAY ]) {
89
+ int updelay = nla_get_u32 (data [IFLA_BOND_UPDELAY ]);
90
+
91
+ err = bond_option_updelay_set (bond , updelay );
92
+ if (err )
93
+ return err ;
94
+ }
95
+ if (data [IFLA_BOND_DOWNDELAY ]) {
96
+ int downdelay = nla_get_u32 (data [IFLA_BOND_DOWNDELAY ]);
97
+
98
+ err = bond_option_downdelay_set (bond , downdelay );
99
+ if (err )
100
+ return err ;
101
+ }
102
+ if (data [IFLA_BOND_USE_CARRIER ]) {
103
+ int use_carrier = nla_get_u8 (data [IFLA_BOND_USE_CARRIER ]);
104
+
105
+ err = bond_option_use_carrier_set (bond , use_carrier );
106
+ if (err )
107
+ return err ;
108
+ }
109
+ if (data [IFLA_BOND_ARP_INTERVAL ]) {
110
+ int arp_interval = nla_get_u32 (data [IFLA_BOND_ARP_INTERVAL ]);
111
+
112
+ if (arp_interval && miimon ) {
113
+ pr_err ("%s: ARP monitoring cannot be used with MII monitoring.\n" ,
114
+ bond -> dev -> name );
115
+ return - EINVAL ;
116
+ }
117
+
118
+ err = bond_option_arp_interval_set (bond , arp_interval );
119
+ if (err )
120
+ return err ;
121
+ }
122
+ if (data [IFLA_BOND_ARP_IP_TARGET ]) {
123
+ __be32 targets [BOND_MAX_ARP_TARGETS ] = { 0 , };
124
+ struct nlattr * attr ;
125
+ int i = 0 , rem ;
126
+
127
+ nla_for_each_nested (attr , data [IFLA_BOND_ARP_IP_TARGET ], rem ) {
128
+ __be32 target = nla_get_u32 (attr );
129
+ targets [i ++ ] = target ;
130
+ }
131
+
132
+ err = bond_option_arp_ip_targets_set (bond , targets , i );
133
+ if (err )
134
+ return err ;
135
+ }
136
+ if (data [IFLA_BOND_ARP_VALIDATE ]) {
137
+ int arp_validate = nla_get_u32 (data [IFLA_BOND_ARP_VALIDATE ]);
138
+
139
+ if (arp_validate && miimon ) {
140
+ pr_err ("%s: ARP validating cannot be used with MII monitoring.\n" ,
141
+ bond -> dev -> name );
142
+ return - EINVAL ;
143
+ }
144
+
145
+ err = bond_option_arp_validate_set (bond , arp_validate );
146
+ if (err )
147
+ return err ;
148
+ }
149
+ if (data [IFLA_BOND_ARP_ALL_TARGETS ]) {
150
+ int arp_all_targets =
151
+ nla_get_u32 (data [IFLA_BOND_ARP_ALL_TARGETS ]);
152
+
153
+ err = bond_option_arp_all_targets_set (bond , arp_all_targets );
154
+ if (err )
155
+ return err ;
156
+ }
68
157
return 0 ;
69
158
}
70
159
@@ -83,19 +172,75 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
83
172
static size_t bond_get_size (const struct net_device * bond_dev )
84
173
{
85
174
return nla_total_size (sizeof (u8 )) + /* IFLA_BOND_MODE */
86
- nla_total_size (sizeof (u32 )); /* IFLA_BOND_ACTIVE_SLAVE */
175
+ nla_total_size (sizeof (u32 )) + /* IFLA_BOND_ACTIVE_SLAVE */
176
+ nla_total_size (sizeof (u32 )) + /* IFLA_BOND_MIIMON */
177
+ nla_total_size (sizeof (u32 )) + /* IFLA_BOND_UPDELAY */
178
+ nla_total_size (sizeof (u32 )) + /* IFLA_BOND_DOWNDELAY */
179
+ nla_total_size (sizeof (u8 )) + /* IFLA_BOND_USE_CARRIER */
180
+ nla_total_size (sizeof (u32 )) + /* IFLA_BOND_ARP_INTERVAL */
181
+ /* IFLA_BOND_ARP_IP_TARGET */
182
+ nla_total_size (sizeof (u32 )) * BOND_MAX_ARP_TARGETS +
183
+ nla_total_size (sizeof (u32 )) + /* IFLA_BOND_ARP_VALIDATE */
184
+ nla_total_size (sizeof (u32 )) + /* IFLA_BOND_ARP_ALL_TARGETS */
185
+ 0 ;
87
186
}
88
187
89
188
static int bond_fill_info (struct sk_buff * skb ,
90
189
const struct net_device * bond_dev )
91
190
{
92
191
struct bonding * bond = netdev_priv (bond_dev );
93
192
struct net_device * slave_dev = bond_option_active_slave_get (bond );
193
+ struct nlattr * targets ;
194
+ int i , targets_added ;
195
+
196
+ if (nla_put_u8 (skb , IFLA_BOND_MODE , bond -> params .mode ))
197
+ goto nla_put_failure ;
198
+
199
+ if (slave_dev &&
200
+ nla_put_u32 (skb , IFLA_BOND_ACTIVE_SLAVE , slave_dev -> ifindex ))
201
+ goto nla_put_failure ;
202
+
203
+ if (nla_put_u32 (skb , IFLA_BOND_MIIMON , bond -> params .miimon ))
204
+ goto nla_put_failure ;
205
+
206
+ if (nla_put_u32 (skb , IFLA_BOND_UPDELAY ,
207
+ bond -> params .updelay * bond -> params .miimon ))
208
+ goto nla_put_failure ;
209
+
210
+ if (nla_put_u32 (skb , IFLA_BOND_DOWNDELAY ,
211
+ bond -> params .downdelay * bond -> params .miimon ))
212
+ goto nla_put_failure ;
213
+
214
+ if (nla_put_u8 (skb , IFLA_BOND_USE_CARRIER , bond -> params .use_carrier ))
215
+ goto nla_put_failure ;
216
+
217
+ if (nla_put_u32 (skb , IFLA_BOND_ARP_INTERVAL , bond -> params .arp_interval ))
218
+ goto nla_put_failure ;
219
+
220
+ targets = nla_nest_start (skb , IFLA_BOND_ARP_IP_TARGET );
221
+ if (!targets )
222
+ goto nla_put_failure ;
223
+
224
+ targets_added = 0 ;
225
+ for (i = 0 ; i < BOND_MAX_ARP_TARGETS ; i ++ ) {
226
+ if (bond -> params .arp_targets [i ]) {
227
+ nla_put_u32 (skb , i , bond -> params .arp_targets [i ]);
228
+ targets_added = 1 ;
229
+ }
230
+ }
94
231
95
- if (nla_put_u8 (skb , IFLA_BOND_MODE , bond -> params .mode ) ||
96
- (slave_dev &&
97
- nla_put_u32 (skb , IFLA_BOND_ACTIVE_SLAVE , slave_dev -> ifindex )))
232
+ if (targets_added )
233
+ nla_nest_end (skb , targets );
234
+ else
235
+ nla_nest_cancel (skb , targets );
236
+
237
+ if (nla_put_u32 (skb , IFLA_BOND_ARP_VALIDATE , bond -> params .arp_validate ))
238
+ goto nla_put_failure ;
239
+
240
+ if (nla_put_u32 (skb , IFLA_BOND_ARP_ALL_TARGETS ,
241
+ bond -> params .arp_all_targets ))
98
242
goto nla_put_failure ;
243
+
99
244
return 0 ;
100
245
101
246
nla_put_failure :
0 commit comments