aboutsummaryrefslogtreecommitdiffstats
path: root/net/bridge
diff options
context:
space:
mode:
authorJohn Fastabend <john.r.fastabend@intel.com>2012-10-24 04:12:57 -0400
committerDavid S. Miller <davem@davemloft.net>2012-10-31 13:18:28 -0400
commite5a55a898720096f43bc24938f8875c0a1b34cd7 (patch)
treeaff4a209c158a6bee5d974647ec8726f2b9a81c0 /net/bridge
parenta932657f51eadb8280166e82dc7034dfbff3985a (diff)
net: create generic bridge ops
The PF_BRIDGE:RTM_{GET|SET}LINK nlmsg family and type are currently embedded in the ./net/bridge module. This prohibits them from being used by other bridging devices. One example of this being hardware that has embedded bridging components. In order to use these nlmsg types more generically this patch adds two net_device_ops hooks. One to set link bridge attributes and another to dump the current bride attributes. ndo_bridge_setlink() ndo_bridge_getlink() CC: Lennert Buytenhek <buytenh@wantstofly.org> CC: Stephen Hemminger <shemminger@vyatta.com> Signed-off-by: John Fastabend <john.r.fastabend@intel.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge')
-rw-r--r--net/bridge/br_device.c2
-rw-r--r--net/bridge/br_netlink.c73
-rw-r--r--net/bridge/br_private.h3
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
318static void br_dev_free(struct net_device *dev) 320static 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 */
114static int br_dump_ifinfo(struct sk_buff *skb, struct netlink_callback *cb) 114int 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;
134skip:
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);
125out:
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 */
147static int br_rtm_setlink(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) 133int 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
219int __init br_netlink_init(void) 194int __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
238err3:
239 rtnl_unregister_all(PF_BRIDGE);
240err2:
241 rtnl_link_unregister(&br_link_ops);
242err1:
243 return err;
244} 197}
245 198
246void __exit br_netlink_fini(void) 199void __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;
553extern int br_netlink_init(void); 553extern int br_netlink_init(void);
554extern void br_netlink_fini(void); 554extern void br_netlink_fini(void);
555extern void br_ifinfo_notify(int event, struct net_bridge_port *port); 555extern void br_ifinfo_notify(int event, struct net_bridge_port *port);
556extern int br_setlink(struct net_device *dev, struct nlmsghdr *nlmsg);
557extern 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 */