aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
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/core
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/core')
-rw-r--r--net/core/rtnetlink.c80
1 files changed, 80 insertions, 0 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 64fe3cca2a4e..a068666b322f 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2252,6 +2252,83 @@ static int rtnl_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb)
2252 return skb->len; 2252 return skb->len;
2253} 2253}
2254 2254
2255static int rtnl_bridge_getlink(struct sk_buff *skb, struct netlink_callback *cb)
2256{
2257 struct net *net = sock_net(skb->sk);
2258 struct net_device *dev;
2259 int idx = 0;
2260 u32 portid = NETLINK_CB(cb->skb).portid;
2261 u32 seq = cb->nlh->nlmsg_seq;
2262
2263 rcu_read_lock();
2264 for_each_netdev_rcu(net, dev) {
2265 const struct net_device_ops *ops = dev->netdev_ops;
2266 struct net_device *master = dev->master;
2267
2268 if (idx < cb->args[0])
2269 continue;
2270
2271 if (master && master->netdev_ops->ndo_bridge_getlink) {
2272 const struct net_device_ops *bops = master->netdev_ops;
2273 int err = bops->ndo_bridge_getlink(skb, portid,
2274 seq, dev);
2275
2276 if (err < 0)
2277 break;
2278 else
2279 idx++;
2280 }
2281
2282 if (ops->ndo_bridge_getlink) {
2283 int err = ops->ndo_bridge_getlink(skb, portid,
2284 seq, dev);
2285
2286 if (err < 0)
2287 break;
2288 else
2289 idx++;
2290 }
2291 }
2292 rcu_read_unlock();
2293 cb->args[0] = idx;
2294
2295 return skb->len;
2296}
2297
2298static int rtnl_bridge_setlink(struct sk_buff *skb, struct nlmsghdr *nlh,
2299 void *arg)
2300{
2301 struct net *net = sock_net(skb->sk);
2302 struct ifinfomsg *ifm;
2303 struct net_device *dev;
2304 int err = -EINVAL;
2305
2306 if (nlmsg_len(nlh) < sizeof(*ifm))
2307 return -EINVAL;
2308
2309 ifm = nlmsg_data(nlh);
2310 if (ifm->ifi_family != AF_BRIDGE)
2311 return -EPFNOSUPPORT;
2312
2313 dev = __dev_get_by_index(net, ifm->ifi_index);
2314 if (!dev) {
2315 pr_info("PF_BRIDGE: RTM_SETLINK with unknown ifindex\n");
2316 return -ENODEV;
2317 }
2318
2319 if (dev->master && dev->master->netdev_ops->ndo_bridge_setlink) {
2320 err = dev->master->netdev_ops->ndo_bridge_setlink(dev, nlh);
2321 if (err)
2322 goto out;
2323 }
2324
2325 if (dev->netdev_ops->ndo_bridge_setlink)
2326 err = dev->netdev_ops->ndo_bridge_setlink(dev, nlh);
2327
2328out:
2329 return err;
2330}
2331
2255/* Protected by RTNL sempahore. */ 2332/* Protected by RTNL sempahore. */
2256static struct rtattr **rta_buf; 2333static struct rtattr **rta_buf;
2257static int rtattr_max; 2334static int rtattr_max;
@@ -2433,5 +2510,8 @@ void __init rtnetlink_init(void)
2433 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL); 2510 rtnl_register(PF_BRIDGE, RTM_NEWNEIGH, rtnl_fdb_add, NULL, NULL);
2434 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL); 2511 rtnl_register(PF_BRIDGE, RTM_DELNEIGH, rtnl_fdb_del, NULL, NULL);
2435 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL); 2512 rtnl_register(PF_BRIDGE, RTM_GETNEIGH, NULL, rtnl_fdb_dump, NULL);
2513
2514 rtnl_register(PF_BRIDGE, RTM_GETLINK, NULL, rtnl_bridge_getlink, NULL);
2515 rtnl_register(PF_BRIDGE, RTM_SETLINK, rtnl_bridge_setlink, NULL, NULL);
2436} 2516}
2437 2517