diff options
Diffstat (limited to 'net/bridge')
-rw-r--r-- | net/bridge/br_device.c | 2 | ||||
-rw-r--r-- | net/bridge/br_netlink.c | 73 | ||||
-rw-r--r-- | net/bridge/br_private.h | 3 |
3 files changed, 18 insertions, 60 deletions
diff --git a/net/bridge/br_device.c b/net/bridge/br_device.c index 070e8a68cfc6..63b5b088e80f 100644 --- a/net/bridge/br_device.c +++ b/net/bridge/br_device.c | |||
@@ -313,6 +313,8 @@ static const struct net_device_ops br_netdev_ops = { | |||
313 | .ndo_fdb_add = br_fdb_add, | 313 | .ndo_fdb_add = br_fdb_add, |
314 | .ndo_fdb_del = br_fdb_delete, | 314 | .ndo_fdb_del = br_fdb_delete, |
315 | .ndo_fdb_dump = br_fdb_dump, | 315 | .ndo_fdb_dump = br_fdb_dump, |
316 | .ndo_bridge_getlink = br_getlink, | ||
317 | .ndo_bridge_setlink = br_setlink, | ||
316 | }; | 318 | }; |
317 | 319 | ||
318 | static void br_dev_free(struct net_device *dev) | 320 | static void br_dev_free(struct net_device *dev) |
diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c index 093f527276a3..743511bb7319 100644 --- a/net/bridge/br_netlink.c +++ b/net/bridge/br_netlink.c | |||
@@ -111,54 +111,33 @@ errout: | |||
111 | /* | 111 | /* |
112 | * Dump information about all ports, in response to GETLINK | 112 | * Dump information about all ports, in response to GETLINK |
113 | */ | 113 | */ |
114 | static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) | 114 | int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, |
115 | struct net_device *dev) | ||
115 | { | 116 | { |
116 | struct net *net = sock_net(skb->sk); | 117 | int err = 0; |
117 | struct net_device *dev; | 118 | struct net_bridge_port *port = br_port_get_rcu(dev); |
118 | int idx; | 119 | |
119 | 120 | /* not a bridge port */ | |
120 | idx = 0; | 121 | if (!port) |
121 | rcu_read_lock(); | 122 | goto out; |
122 | for_each_netdev_rcu(net, dev) { | ||
123 | struct net_bridge_port *port = br_port_get_rcu(dev); | ||
124 | |||
125 | /* not a bridge port */ | ||
126 | if (!port || idx < cb->args[0]) | ||
127 | goto skip; | ||
128 | |||
129 | if (br_fill_ifinfo(skb, port, | ||
130 | NETLINK_CB(cb->skb).portid, | ||
131 | cb->nlh->nlmsg_seq, RTM_NEWLINK, | ||
132 | NLM_F_MULTI) < 0) | ||
133 | break; | ||
134 | skip: | ||
135 | ++idx; | ||
136 | } | ||
137 | rcu_read_unlock(); | ||
138 | cb->args[0] = idx; | ||
139 | 123 | ||
140 | return skb->len; | 124 | err = br_fill_ifinfo(skb, port, pid, seq, RTM_NEWLINK, NLM_F_MULTI); |
125 | out: | ||
126 | return err; | ||
141 | } | 127 | } |
142 | 128 | ||
143 | /* | 129 | /* |
144 | * Change state of port (ie from forwarding to blocking etc) | 130 | * Change state of port (ie from forwarding to blocking etc) |
145 | * Used by spanning tree in user space. | 131 | * Used by spanning tree in user space. |
146 | */ | 132 | */ |
147 | static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | 133 | int br_setlink(struct net_device *dev, struct nlmsghdr *nlh) |
148 | { | 134 | { |
149 | struct net *net = sock_net(skb->sk); | ||
150 | struct ifinfomsg *ifm; | 135 | struct ifinfomsg *ifm; |
151 | struct nlattr *protinfo; | 136 | struct nlattr *protinfo; |
152 | struct net_device *dev; | ||
153 | struct net_bridge_port *p; | 137 | struct net_bridge_port *p; |
154 | u8 new_state; | 138 | u8 new_state; |
155 | 139 | ||
156 | if (nlmsg_len(nlh) < sizeof(*ifm)) | ||
157 | return -EINVAL; | ||
158 | |||
159 | ifm = nlmsg_data(nlh); | 140 | ifm = nlmsg_data(nlh); |
160 | if (ifm->ifi_family != AF_BRIDGE) | ||
161 | return -EPFNOSUPPORT; | ||
162 | 141 | ||
163 | protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); | 142 | protinfo = nlmsg_find_attr(nlh, sizeof(*ifm), IFLA_PROTINFO); |
164 | if (!protinfo || nla_len(protinfo) < sizeof(u8)) | 143 | if (!protinfo || nla_len(protinfo) < sizeof(u8)) |
@@ -168,10 +147,6 @@ static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) | |||
168 | if (new_state > BR_STATE_BLOCKING) | 147 | if (new_state > BR_STATE_BLOCKING) |
169 | return -EINVAL; | 148 | return -EINVAL; |
170 | 149 | ||
171 | dev = __dev_get_by_index(net, ifm->ifi_index); | ||
172 | if (!dev) | ||
173 | return -ENODEV; | ||
174 | |||
175 | p = br_port_get_rtnl(dev); | 150 | p = br_port_get_rtnl(dev); |
176 | if (!p) | 151 | if (!p) |
177 | return -EINVAL; | 152 | return -EINVAL; |
@@ -218,29 +193,7 @@ struct rtnl_link_ops br_link_ops __read_mostly = { | |||
218 | 193 | ||
219 | int __init br_netlink_init(void) | 194 | int __init br_netlink_init(void) |
220 | { | 195 | { |
221 | int err; | 196 | return rtnl_link_register(&br_link_ops); |
222 | |||
223 | err = rtnl_link_register(&br_link_ops); | ||
224 | if (err < 0) | ||
225 | goto err1; | ||
226 | |||
227 | err = __rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, | ||
228 | br_dump_ifinfo, NULL); | ||
229 | if (err) | ||
230 | goto err2; | ||
231 | err = __rtnl_register(PF_BRIDGE, RTM_SETLINK, | ||
232 | br_rtm_setlink, NULL, NULL); | ||
233 | if (err) | ||
234 | goto err3; | ||
235 | |||
236 | return 0; | ||
237 | |||
238 | err3: | ||
239 | rtnl_unregister_all(PF_BRIDGE); | ||
240 | err2: | ||
241 | rtnl_link_unregister(&br_link_ops); | ||
242 | err1: | ||
243 | return err; | ||
244 | } | 197 | } |
245 | 198 | ||
246 | void __exit br_netlink_fini(void) | 199 | void __exit br_netlink_fini(void) |
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 9b278c4ebee1..fdcd5f626ca6 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h | |||
@@ -553,6 +553,9 @@ extern struct rtnl_link_ops br_link_ops; | |||
553 | extern int br_netlink_init(void); | 553 | extern int br_netlink_init(void); |
554 | extern void br_netlink_fini(void); | 554 | extern void br_netlink_fini(void); |
555 | extern void br_ifinfo_notify(int event, struct net_bridge_port *port); | 555 | extern void br_ifinfo_notify(int event, struct net_bridge_port *port); |
556 | extern int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg); | ||
557 | extern int br_getlink(struct sk_buff *skb, u32 pid, u32 seq, | ||
558 | struct net_device *dev); | ||
556 | 559 | ||
557 | #ifdef CONFIG_SYSFS | 560 | #ifdef CONFIG_SYSFS |
558 | /* br_sysfs_if.c */ | 561 | /* br_sysfs_if.c */ |