Commit f6f6424ba773da6221ecaaa70973eb4dacfa03b2

Authored by Jiri Pirko
Committed by David S. Miller
1 parent 93859b13fa

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>

Showing 10 changed files with 70 additions and 60 deletions Side-by-side Diff

drivers/net/ethernet/intel/i40e/i40e_main.c
... ... @@ -7536,7 +7536,7 @@
7536 7536 */
7537 7537 static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
7538 7538 struct net_device *dev,
7539   - const unsigned char *addr,
  7539 + const unsigned char *addr, u16 vid,
7540 7540 u16 flags)
7541 7541 {
7542 7542 struct i40e_netdev_priv *np = netdev_priv(dev);
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
... ... @@ -7708,7 +7708,7 @@
7708 7708  
7709 7709 static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
7710 7710 struct net_device *dev,
7711   - const unsigned char *addr,
  7711 + const unsigned char *addr, u16 vid,
7712 7712 u16 flags)
7713 7713 {
7714 7714 /* guarantee we can provide a unique filter for the unicast address */
... ... @@ -7717,7 +7717,7 @@
7717 7717 return -ENOMEM;
7718 7718 }
7719 7719  
7720   - return ndo_dflt_fdb_add(ndm, tb, dev, addr, flags);
  7720 + return ndo_dflt_fdb_add(ndm, tb, dev, addr, vid, flags);
7721 7721 }
7722 7722  
7723 7723 static int ixgbe_ndo_bridge_setlink(struct net_device *dev,
drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
... ... @@ -376,13 +376,14 @@
376 376 }
377 377  
378 378 static int qlcnic_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
379   - struct net_device *netdev, const unsigned char *addr)
  379 + struct net_device *netdev,
  380 + const unsigned char *addr, u16 vid)
380 381 {
381 382 struct qlcnic_adapter *adapter = netdev_priv(netdev);
382 383 int err = -EOPNOTSUPP;
383 384  
384 385 if (!adapter->fdb_mac_learn)
385   - return ndo_dflt_fdb_del(ndm, tb, netdev, addr);
  386 + return ndo_dflt_fdb_del(ndm, tb, netdev, addr, vid);
386 387  
387 388 if ((adapter->flags & QLCNIC_ESWITCH_ENABLED) ||
388 389 qlcnic_sriov_check(adapter)) {
389 390  
... ... @@ -401,13 +402,13 @@
401 402  
402 403 static int qlcnic_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
403 404 struct net_device *netdev,
404   - const unsigned char *addr, u16 flags)
  405 + const unsigned char *addr, u16 vid, u16 flags)
405 406 {
406 407 struct qlcnic_adapter *adapter = netdev_priv(netdev);
407 408 int err = 0;
408 409  
409 410 if (!adapter->fdb_mac_learn)
410   - return ndo_dflt_fdb_add(ndm, tb, netdev, addr, flags);
  411 + return ndo_dflt_fdb_add(ndm, tb, netdev, addr, vid, flags);
411 412  
412 413 if (!(adapter->flags & QLCNIC_ESWITCH_ENABLED) &&
413 414 !qlcnic_sriov_check(adapter)) {
drivers/net/macvlan.c
... ... @@ -873,7 +873,7 @@
873 873  
874 874 static int macvlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
875 875 struct net_device *dev,
876   - const unsigned char *addr,
  876 + const unsigned char *addr, u16 vid,
877 877 u16 flags)
878 878 {
879 879 struct macvlan_dev *vlan = netdev_priv(dev);
... ... @@ -898,7 +898,7 @@
898 898  
899 899 static int macvlan_fdb_del(struct ndmsg *ndm, struct nlattr *tb[],
900 900 struct net_device *dev,
901   - const unsigned char *addr)
  901 + const unsigned char *addr, u16 vid)
902 902 {
903 903 struct macvlan_dev *vlan = netdev_priv(dev);
904 904 int err = -EINVAL;
... ... @@ -849,7 +849,7 @@
849 849 /* Add static entry (via netlink) */
850 850 static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
851 851 struct net_device *dev,
852   - const unsigned char *addr, u16 flags)
  852 + const unsigned char *addr, u16 vid, u16 flags)
853 853 {
854 854 struct vxlan_dev *vxlan = netdev_priv(dev);
855 855 /* struct net *net = dev_net(vxlan->dev); */
... ... @@ -885,7 +885,7 @@
885 885 /* Delete entry (via netlink) */
886 886 static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
887 887 struct net_device *dev,
888   - const unsigned char *addr)
  888 + const unsigned char *addr, u16 vid)
889 889 {
890 890 struct vxlan_dev *vxlan = netdev_priv(dev);
891 891 struct vxlan_fdb *f;
include/linux/netdevice.h
... ... @@ -951,11 +951,11 @@
951 951 *
952 952 * int (*ndo_fdb_add)(struct ndmsg *ndm, struct nlattr *tb[],
953 953 * struct net_device *dev,
954   - * const unsigned char *addr, u16 flags)
  954 + * const unsigned char *addr, u16 vid, u16 flags)
955 955 * Adds an FDB entry to dev for addr.
956 956 * int (*ndo_fdb_del)(struct ndmsg *ndm, struct nlattr *tb[],
957 957 * struct net_device *dev,
958   - * const unsigned char *addr)
  958 + * const unsigned char *addr, u16 vid)
959 959 * Deletes the FDB entry from dev coresponding to addr.
960 960 * int (*ndo_fdb_dump)(struct sk_buff *skb, struct netlink_callback *cb,
961 961 * struct net_device *dev, struct net_device *filter_dev,
962 962  
... ... @@ -1128,11 +1128,13 @@
1128 1128 struct nlattr *tb[],
1129 1129 struct net_device *dev,
1130 1130 const unsigned char *addr,
  1131 + u16 vid,
1131 1132 u16 flags);
1132 1133 int (*ndo_fdb_del)(struct ndmsg *ndm,
1133 1134 struct nlattr *tb[],
1134 1135 struct net_device *dev,
1135   - const unsigned char *addr);
  1136 + const unsigned char *addr,
  1137 + u16 vid);
1136 1138 int (*ndo_fdb_dump)(struct sk_buff *skb,
1137 1139 struct netlink_callback *cb,
1138 1140 struct net_device *dev,
include/linux/rtnetlink.h
... ... @@ -94,11 +94,13 @@
94 94 struct nlattr *tb[],
95 95 struct net_device *dev,
96 96 const unsigned char *addr,
97   - u16 flags);
  97 + u16 vid,
  98 + u16 flags);
98 99 extern int ndo_dflt_fdb_del(struct ndmsg *ndm,
99 100 struct nlattr *tb[],
100 101 struct net_device *dev,
101   - const unsigned char *addr);
  102 + const unsigned char *addr,
  103 + u16 vid);
102 104  
103 105 extern int ndo_dflt_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
104 106 struct net_device *dev, u16 mode);
... ... @@ -805,33 +805,17 @@
805 805 /* Add new permanent fdb entry with RTM_NEWNEIGH */
806 806 int br_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
807 807 struct net_device *dev,
808   - const unsigned char *addr, u16 nlh_flags)
  808 + const unsigned char *addr, u16 vid, u16 nlh_flags)
809 809 {
810 810 struct net_bridge_port *p;
811 811 int err = 0;
812 812 struct net_port_vlans *pv;
813   - unsigned short vid = VLAN_N_VID;
814 813  
815 814 if (!(ndm->ndm_state & (NUD_PERMANENT|NUD_NOARP|NUD_REACHABLE))) {
816 815 pr_info("bridge: RTM_NEWNEIGH with invalid state %#x\n", ndm->ndm_state);
817 816 return -EINVAL;
818 817 }
819 818  
820   - if (tb[NDA_VLAN]) {
821   - if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) {
822   - pr_info("bridge: RTM_NEWNEIGH with invalid vlan\n");
823   - return -EINVAL;
824   - }
825   -
826   - vid = nla_get_u16(tb[NDA_VLAN]);
827   -
828   - if (!vid || vid >= VLAN_VID_MASK) {
829   - pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n",
830   - vid);
831   - return -EINVAL;
832   - }
833   - }
834   -
835 819 if (is_zero_ether_addr(addr)) {
836 820 pr_info("bridge: RTM_NEWNEIGH with invalid ether address\n");
837 821 return -EINVAL;
... ... @@ -845,7 +829,7 @@
845 829 }
846 830  
847 831 pv = nbp_get_vlan_info(p);
848   - if (vid != VLAN_N_VID) {
  832 + if (vid) {
849 833 if (!pv || !test_bit(vid, pv->vlan_bitmap)) {
850 834 pr_info("bridge: RTM_NEWNEIGH with unconfigured "
851 835 "vlan %d on port %s\n", vid, dev->name);
852 836  
853 837  
... ... @@ -903,27 +887,12 @@
903 887 /* Remove neighbor entry with RTM_DELNEIGH */
904 888 int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
905 889 struct net_device *dev,
906   - const unsigned char *addr)
  890 + const unsigned char *addr, u16 vid)
907 891 {
908 892 struct net_bridge_port *p;
909 893 int err;
910 894 struct net_port_vlans *pv;
911   - unsigned short vid = VLAN_N_VID;
912 895  
913   - if (tb[NDA_VLAN]) {
914   - if (nla_len(tb[NDA_VLAN]) != sizeof(unsigned short)) {
915   - pr_info("bridge: RTM_NEWNEIGH with invalid vlan\n");
916   - return -EINVAL;
917   - }
918   -
919   - vid = nla_get_u16(tb[NDA_VLAN]);
920   -
921   - if (!vid || vid >= VLAN_VID_MASK) {
922   - pr_info("bridge: RTM_NEWNEIGH with invalid vlan id %d\n",
923   - vid);
924   - return -EINVAL;
925   - }
926   - }
927 896 p = br_port_get_rtnl(dev);
928 897 if (p == NULL) {
929 898 pr_info("bridge: RTM_DELNEIGH %s not a bridge port\n",
... ... @@ -932,7 +901,7 @@
932 901 }
933 902  
934 903 pv = nbp_get_vlan_info(p);
935   - if (vid != VLAN_N_VID) {
  904 + if (vid) {
936 905 if (!pv || !test_bit(vid, pv->vlan_bitmap)) {
937 906 pr_info("bridge: RTM_DELNEIGH with unconfigured "
938 907 "vlan %d on port %s\n", vid, dev->name);
net/bridge/br_private.h
... ... @@ -404,9 +404,9 @@
404 404 const unsigned char *addr, u16 vid, bool added_by_user);
405 405  
406 406 int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
407   - struct net_device *dev, const unsigned char *addr);
  407 + struct net_device *dev, const unsigned char *addr, u16 vid);
408 408 int br_fdb_add(struct ndmsg *nlh, struct nlattr *tb[], struct net_device *dev,
409   - const unsigned char *addr, u16 nlh_flags);
  409 + const unsigned char *addr, u16 vid, u16 nlh_flags);
410 410 int br_fdb_dump(struct sk_buff *skb, struct netlink_callback *cb,
411 411 struct net_device *dev, struct net_device *fdev, int idx);
412 412 int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p);
net/core/rtnetlink.c
... ... @@ -36,6 +36,7 @@
36 36 #include <linux/mutex.h>
37 37 #include <linux/if_addr.h>
38 38 #include <linux/if_bridge.h>
  39 +#include <linux/if_vlan.h>
39 40 #include <linux/pci.h>
40 41 #include <linux/etherdevice.h>
41 42  
... ... @@ -2312,7 +2313,7 @@
2312 2313 int ndo_dflt_fdb_add(struct ndmsg *ndm,
2313 2314 struct nlattr *tb[],
2314 2315 struct net_device *dev,
2315   - const unsigned char *addr,
  2316 + const unsigned char *addr, u16 vid,
2316 2317 u16 flags)
2317 2318 {
2318 2319 int err = -EINVAL;
... ... @@ -2338,6 +2339,28 @@
2338 2339 }
2339 2340 EXPORT_SYMBOL(ndo_dflt_fdb_add);
2340 2341  
  2342 +static 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 +
2341 2364 static int rtnl_fdb_add(struct sk_buff *skb, struct nlmsghdr *nlh)
2342 2365 {
2343 2366 struct net *net = sock_net(skb->sk);
... ... @@ -2345,6 +2368,7 @@
2345 2368 struct nlattr *tb[NDA_MAX+1];
2346 2369 struct net_device *dev;
2347 2370 u8 *addr;
  2371 + u16 vid;
2348 2372 int err;
2349 2373  
2350 2374 err = nlmsg_parse(nlh, sizeof(*ndm), tb, NDA_MAX, NULL);
... ... @@ -2370,6 +2394,10 @@
2370 2394  
2371 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 2401 err = -EOPNOTSUPP;
2374 2402  
2375 2403 /* Support fdb on master device the net/bridge default case */
... ... @@ -2378,7 +2406,8 @@
2378 2406 struct net_device *br_dev = netdev_master_upper_dev_get(dev);
2379 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 2411 if (err)
2383 2412 goto out;
2384 2413 else
2385 2414  
... ... @@ -2389,9 +2418,10 @@
2389 2418 if ((ndm->ndm_flags & NTF_SELF)) {
2390 2419 if (dev->netdev_ops->ndo_fdb_add)
2391 2420 err = dev->netdev_ops->ndo_fdb_add(ndm, tb, dev, addr,
  2421 + vid,
2392 2422 nlh->nlmsg_flags);
2393 2423 else
2394   - err = ndo_dflt_fdb_add(ndm, tb, dev, addr,
  2424 + err = ndo_dflt_fdb_add(ndm, tb, dev, addr, vid,
2395 2425 nlh->nlmsg_flags);
2396 2426  
2397 2427 if (!err) {
... ... @@ -2409,7 +2439,7 @@
2409 2439 int ndo_dflt_fdb_del(struct ndmsg *ndm,
2410 2440 struct nlattr *tb[],
2411 2441 struct net_device *dev,
2412   - const unsigned char *addr)
  2442 + const unsigned char *addr, u16 vid)
2413 2443 {
2414 2444 int err = -EINVAL;
2415 2445  
... ... @@ -2438,6 +2468,7 @@
2438 2468 struct net_device *dev;
2439 2469 int err = -EINVAL;
2440 2470 __u8 *addr;
  2471 + u16 vid;
2441 2472  
2442 2473 if (!netlink_capable(skb, CAP_NET_ADMIN))
2443 2474 return -EPERM;
... ... @@ -2465,6 +2496,10 @@
2465 2496  
2466 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 2503 err = -EOPNOTSUPP;
2469 2504  
2470 2505 /* Support fdb on master device the net/bridge default case */
... ... @@ -2474,7 +2509,7 @@
2474 2509 const struct net_device_ops *ops = br_dev->netdev_ops;
2475 2510  
2476 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 2514 if (err)
2480 2515 goto out;
2481 2516  
... ... @@ -2485,9 +2520,10 @@
2485 2520 /* Embedded bridge, macvlan, and any other device support */
2486 2521 if (ndm->ndm_flags & NTF_SELF) {
2487 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 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 2528 if (!err) {
2493 2529 rtnl_fdb_notify(dev, addr, RTM_DELNEIGH);