aboutsummaryrefslogtreecommitdiffstats
path: root/net/core
diff options
context:
space:
mode:
authorJiri Pirko <jiri@resnulli.us>2014-11-28 08:34:15 -0500
committerDavid S. Miller <davem@davemloft.net>2014-12-02 23:01:18 -0500
commitf6f6424ba773da6221ecaaa70973eb4dacfa03b2 (patch)
tree76b4c5cea45c1a569d6cbd2f896e07f6b45d523e /net/core
parent93859b13fa7ecef9d4d8bab4a7acc9f212c8fce2 (diff)
net: make vid as a parameter for ndo_fdb_add/ndo_fdb_del
Do the work of parsing NDA_VLAN directly in rtnetlink code, pass simple u16 vid to drivers from there. Signed-off-by: Jiri Pirko <jiri@resnulli.us> Acked-by: Andy Gospodarek <gospo@cumulusnetworks.com> Acked-by: Jamal Hadi Salim <jhs@mojatatu.com> Acked-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.c50
1 files changed, 43 insertions, 7 deletions
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index b9b7dfaf202b..1a233c1c8ab4 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -36,6 +36,7 @@
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/if_addr.h> 37#include <linux/if_addr.h>
38#include <linux/if_bridge.h> 38#include <linux/if_bridge.h>
39#include <linux/if_vlan.h>
39#include <linux/pci.h> 40#include <linux/pci.h>
40#include <linux/etherdevice.h> 41#include <linux/etherdevice.h>
41 42
@@ -2312,7 +2313,7 @@ errout:
2312int ndo_dflt_fdb_add(struct ndmsg *ndm, 2313int ndo_dflt_fdb_add(struct ndmsg *ndm,
2313 struct nlattr *tb[], 2314 struct nlattr *tb[],
2314 struct net_device *dev, 2315 struct net_device *dev,
2315 const unsigned char *addr, 2316 const unsigned char *addr, u16 vid,
2316 u16 flags) 2317 u16 flags)
2317{ 2318{
2318 int err = -EINVAL; 2319 int err = -EINVAL;
@@ -2338,6 +2339,28 @@ int ndo_dflt_fdb_add(struct ndmsg *ndm,
2338} 2339}
2339EXPORT_SYMBOL(ndo_dflt_fdb_add); 2340EXPORT_SYMBOL(ndo_dflt_fdb_add);
2340 2341
2342static int fdb_vid_parse(struct nlattr *vlan_attr, u16 *p_vid)
2343{
2344 u16 vid = 0;
2345
2346 if (vlan_attr) {
2347 if (nla_len(vlan_attr) != sizeof(u16)) {
2348 pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid vlan\n");
2349 return -EINVAL;
2350 }
2351
2352 vid = nla_get_u16(vlan_attr);
2353
2354 if (!vid || vid >= VLAN_VID_MASK) {
2355 pr_info("PF_BRIDGE: RTM_NEWNEIGH with invalid vlan id %d\n",
2356 vid);
2357 return -EINVAL;
2358 }
2359 }
2360 *p_vid = vid;
2361 return 0;
2362}
2363
2341static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh) 2364static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
2342{ 2365{
2343 struct net *net = sock_net(skb->sk); 2366 struct net *net = sock_net(skb->sk);
@@ -2345,6 +2368,7 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
2345 struct nlattr *tb[NDA_MAX+1]; 2368 struct nlattr *tb[NDA_MAX+1];
2346 struct net_device *dev; 2369 struct net_device *dev;
2347 u8 *addr; 2370 u8 *addr;
2371 u16 vid;
2348 int err; 2372 int err;
2349 2373
2350 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL); 2374 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
@@ -2370,6 +2394,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
2370 2394
2371 addr = nla_data(tb[NDA_LLADDR]); 2395 addr = nla_data(tb[NDA_LLADDR]);
2372 2396
2397 err = fdb_vid_parse(tb[NDA_VLAN], &vid);
2398 if (err)
2399 return err;
2400
2373 err = -EOPNOTSUPP; 2401 err = -EOPNOTSUPP;
2374 2402
2375 /* Support fdb on master device the net/bridge default case */ 2403 /* Support fdb on master device the net/bridge default case */
@@ -2378,7 +2406,8 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
2378 struct net_device *br_dev = netdev_master_upper_dev_get(dev); 2406 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
2379 const struct net_device_ops *ops = br_dev->netdev_ops; 2407 const struct net_device_ops *ops = br_dev->netdev_ops;
2380 2408
2381 err = ops->ndo_fdb_add(ndm, tb, dev, addr, nlh->nlmsg_flags); 2409 err = ops->ndo_fdb_add(ndm, tb, dev, addr, vid,
2410 nlh->nlmsg_flags);
2382 if (err) 2411 if (err)
2383 goto out; 2412 goto out;
2384 else 2413 else
@@ -2389,9 +2418,10 @@ static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
2389 if ((ndm->ndm_flags & NTF_SELF)) { 2418 if ((ndm->ndm_flags & NTF_SELF)) {
2390 if (dev->netdev_ops->ndo_fdb_add) 2419 if (dev->netdev_ops->ndo_fdb_add)
2391 err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr, 2420 err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
2421 vid,
2392 nlh->nlmsg_flags); 2422 nlh->nlmsg_flags);
2393 else 2423 else
2394 err = ndo_dflt_fdb_add(ndm, tb, dev, addr, 2424 err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
2395 nlh->nlmsg_flags); 2425 nlh->nlmsg_flags);
2396 2426
2397 if (!err) { 2427 if (!err) {
@@ -2409,7 +2439,7 @@ out:
2409int ndo_dflt_fdb_del(struct ndmsg *ndm, 2439int ndo_dflt_fdb_del(struct ndmsg *ndm,
2410 struct nlattr *tb[], 2440 struct nlattr *tb[],
2411 struct net_device *dev, 2441 struct net_device *dev,
2412 const unsigned char *addr) 2442 const unsigned char *addr, u16 vid)
2413{ 2443{
2414 int err = -EINVAL; 2444 int err = -EINVAL;
2415 2445
@@ -2438,6 +2468,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
2438 struct net_device *dev; 2468 struct net_device *dev;
2439 int err = -EINVAL; 2469 int err = -EINVAL;
2440 __u8 *addr; 2470 __u8 *addr;
2471 u16 vid;
2441 2472
2442 if (!netlink_capable(skb, CAP_NET_ADMIN)) 2473 if (!netlink_capable(skb, CAP_NET_ADMIN))
2443 return -EPERM; 2474 return -EPERM;
@@ -2465,6 +2496,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
2465 2496
2466 addr = nla_data(tb[NDA_LLADDR]); 2497 addr = nla_data(tb[NDA_LLADDR]);
2467 2498
2499 err = fdb_vid_parse(tb[NDA_VLAN], &vid);
2500 if (err)
2501 return err;
2502
2468 err = -EOPNOTSUPP; 2503 err = -EOPNOTSUPP;
2469 2504
2470 /* Support fdb on master device the net/bridge default case */ 2505 /* Support fdb on master device the net/bridge default case */
@@ -2474,7 +2509,7 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
2474 const struct net_device_ops *ops = br_dev->netdev_ops; 2509 const struct net_device_ops *ops = br_dev->netdev_ops;
2475 2510
2476 if (ops->ndo_fdb_del) 2511 if (ops->ndo_fdb_del)
2477 err = ops->ndo_fdb_del(ndm, tb, dev, addr); 2512 err = ops->ndo_fdb_del(ndm, tb, dev, addr, vid);
2478 2513
2479 if (err) 2514 if (err)
2480 goto out; 2515 goto out;
@@ -2485,9 +2520,10 @@ static int rtnl_fdb_del(struct sk_buff *skb, struct nlmsghdr *nlh)
2485 /* Embedded bridge, macvlan, and any other device support */ 2520 /* Embedded bridge, macvlan, and any other device support */
2486 if (ndm->ndm_flags & NTF_SELF) { 2521 if (ndm->ndm_flags & NTF_SELF) {
2487 if (dev->netdev_ops->ndo_fdb_del) 2522 if (dev->netdev_ops->ndo_fdb_del)
2488 err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr); 2523 err = dev->netdev_ops->ndo_fdb_del(ndm, tb, dev, addr,
2524 vid);
2489 else 2525 else
2490 err = ndo_dflt_fdb_del(ndm, tb, dev, addr); 2526 err = ndo_dflt_fdb_del(ndm, tb, dev, addr, vid);
2491 2527
2492 if (!err) { 2528 if (!err) {
2493 rtnl_fdb_notify(dev, addr, RTM_DELNEIGH); 2529 rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);