11/*
22 * drivers/net/bond/bond_netlink.c - Netlink interface for bonding
33 * Copyright (c) 2013 Jiri Pirko <jiri@resnulli.us>
4+ * Copyright (c) 2013 Scott Feldman <sfeldma@cumulusnetworks.com>
45 *
56 * This program is free software; you can redistribute it and/or modify
67 * it under the terms of the GNU General Public License as published by
2324static const struct nla_policy bond_policy [IFLA_BOND_MAX + 1 ] = {
2425 [IFLA_BOND_MODE ] = { .type = NLA_U8 },
2526 [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 },
2635};
2736
2837static int bond_validate (struct nlattr * tb [], struct nlattr * data [])
@@ -40,16 +49,20 @@ static int bond_changelink(struct net_device *bond_dev,
4049 struct nlattr * tb [], struct nlattr * data [])
4150{
4251 struct bonding * bond = netdev_priv (bond_dev );
52+ int miimon = 0 ;
4353 int err ;
4454
45- if (data && data [IFLA_BOND_MODE ]) {
55+ if (!data )
56+ return 0 ;
57+
58+ if (data [IFLA_BOND_MODE ]) {
4659 int mode = nla_get_u8 (data [IFLA_BOND_MODE ]);
4760
4861 err = bond_option_mode_set (bond , mode );
4962 if (err )
5063 return err ;
5164 }
52- if (data && data [IFLA_BOND_ACTIVE_SLAVE ]) {
65+ if (data [IFLA_BOND_ACTIVE_SLAVE ]) {
5366 int ifindex = nla_get_u32 (data [IFLA_BOND_ACTIVE_SLAVE ]);
5467 struct net_device * slave_dev ;
5568
@@ -65,6 +78,82 @@ static int bond_changelink(struct net_device *bond_dev,
6578 if (err )
6679 return err ;
6780 }
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+ }
68157 return 0 ;
69158}
70159
@@ -83,19 +172,75 @@ static int bond_newlink(struct net *src_net, struct net_device *bond_dev,
83172static size_t bond_get_size (const struct net_device * bond_dev )
84173{
85174 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 ;
87186}
88187
89188static int bond_fill_info (struct sk_buff * skb ,
90189 const struct net_device * bond_dev )
91190{
92191 struct bonding * bond = netdev_priv (bond_dev );
93192 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+ }
94231
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 ))
98242 goto nla_put_failure ;
243+
99244 return 0 ;
100245
101246nla_put_failure :
0 commit comments