Commit f6f6424ba773da6221ecaaa70973eb4dacfa03b2
Committed by
David S. Miller
1 parent
93859b13fa
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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; |
drivers/net/vxlan.c
... | ... | @@ -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); |
net/bridge/br_fdb.c
... | ... | @@ -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); |
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f
-
mentioned in commit 65891f