diff options
author | Jiri Pirko <jiri@resnulli.us> | 2014-11-28 08:34:29 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-12-02 23:01:26 -0500 |
commit | ce76ca689dfe0bafba21b0dc002c7f92eb629fd8 (patch) | |
tree | 0021dd94e3efe0d435d05e4574866120e09e2f81 | |
parent | 6c7079450071f889b4c2b55f8d030b1a5e859401 (diff) |
rocker: implement ndo_fdb_dump
Signed-off-by: Jiri Pirko <jiri@resnulli.us>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/ethernet/rocker/rocker.c | 73 |
1 files changed, 73 insertions, 0 deletions
diff --git a/drivers/net/ethernet/rocker/rocker.c b/drivers/net/ethernet/rocker/rocker.c index 6c15aa1e4b60..fea49e8cf8ef 100644 --- a/drivers/net/ethernet/rocker/rocker.c +++ b/drivers/net/ethernet/rocker/rocker.c | |||
@@ -3587,6 +3587,78 @@ static int rocker_port_fdb_del(struct ndmsg *ndm, struct nlattr *tb[], | |||
3587 | return rocker_port_fdb(rocker_port, addr, vlan_id, flags); | 3587 | return rocker_port_fdb(rocker_port, addr, vlan_id, flags); |
3588 | } | 3588 | } |
3589 | 3589 | ||
3590 | static int rocker_fdb_fill_info(struct sk_buff *skb, | ||
3591 | struct rocker_port *rocker_port, | ||
3592 | const unsigned char *addr, u16 vid, | ||
3593 | u32 portid, u32 seq, int type, | ||
3594 | unsigned int flags) | ||
3595 | { | ||
3596 | struct nlmsghdr *nlh; | ||
3597 | struct ndmsg *ndm; | ||
3598 | |||
3599 | nlh = nlmsg_put(skb, portid, seq, type, sizeof(*ndm), flags); | ||
3600 | if (!nlh) | ||
3601 | return -EMSGSIZE; | ||
3602 | |||
3603 | ndm = nlmsg_data(nlh); | ||
3604 | ndm->ndm_family = AF_BRIDGE; | ||
3605 | ndm->ndm_pad1 = 0; | ||
3606 | ndm->ndm_pad2 = 0; | ||
3607 | ndm->ndm_flags = NTF_SELF; | ||
3608 | ndm->ndm_type = 0; | ||
3609 | ndm->ndm_ifindex = rocker_port->dev->ifindex; | ||
3610 | ndm->ndm_state = NUD_REACHABLE; | ||
3611 | |||
3612 | if (nla_put(skb, NDA_LLADDR, ETH_ALEN, addr)) | ||
3613 | goto nla_put_failure; | ||
3614 | |||
3615 | if (vid && nla_put_u16(skb, NDA_VLAN, vid)) | ||
3616 | goto nla_put_failure; | ||
3617 | |||
3618 | return nlmsg_end(skb, nlh); | ||
3619 | |||
3620 | nla_put_failure: | ||
3621 | nlmsg_cancel(skb, nlh); | ||
3622 | return -EMSGSIZE; | ||
3623 | } | ||
3624 | |||
3625 | static int rocker_port_fdb_dump(struct sk_buff *skb, | ||
3626 | struct netlink_callback *cb, | ||
3627 | struct net_device *dev, | ||
3628 | struct net_device *filter_dev, | ||
3629 | int idx) | ||
3630 | { | ||
3631 | struct rocker_port *rocker_port = netdev_priv(dev); | ||
3632 | struct rocker *rocker = rocker_port->rocker; | ||
3633 | struct rocker_fdb_tbl_entry *found; | ||
3634 | struct hlist_node *tmp; | ||
3635 | int bkt; | ||
3636 | unsigned long lock_flags; | ||
3637 | const unsigned char *addr; | ||
3638 | u16 vid; | ||
3639 | int err; | ||
3640 | |||
3641 | spin_lock_irqsave(&rocker->fdb_tbl_lock, lock_flags); | ||
3642 | hash_for_each_safe(rocker->fdb_tbl, bkt, tmp, found, entry) { | ||
3643 | if (found->key.lport != rocker_port->lport) | ||
3644 | continue; | ||
3645 | if (idx < cb->args[0]) | ||
3646 | goto skip; | ||
3647 | addr = found->key.addr; | ||
3648 | vid = rocker_port_vlan_to_vid(rocker_port, found->key.vlan_id); | ||
3649 | err = rocker_fdb_fill_info(skb, rocker_port, addr, vid, | ||
3650 | NETLINK_CB(cb->skb).portid, | ||
3651 | cb->nlh->nlmsg_seq, | ||
3652 | RTM_NEWNEIGH, NLM_F_MULTI); | ||
3653 | if (err < 0) | ||
3654 | break; | ||
3655 | skip: | ||
3656 | ++idx; | ||
3657 | } | ||
3658 | spin_unlock_irqrestore(&rocker->fdb_tbl_lock, lock_flags); | ||
3659 | return idx; | ||
3660 | } | ||
3661 | |||
3590 | static int rocker_port_switch_parent_id_get(struct net_device *dev, | 3662 | static int rocker_port_switch_parent_id_get(struct net_device *dev, |
3591 | struct netdev_phys_item_id *psid) | 3663 | struct netdev_phys_item_id *psid) |
3592 | { | 3664 | { |
@@ -3614,6 +3686,7 @@ static const struct net_device_ops rocker_port_netdev_ops = { | |||
3614 | .ndo_vlan_rx_kill_vid = rocker_port_vlan_rx_kill_vid, | 3686 | .ndo_vlan_rx_kill_vid = rocker_port_vlan_rx_kill_vid, |
3615 | .ndo_fdb_add = rocker_port_fdb_add, | 3687 | .ndo_fdb_add = rocker_port_fdb_add, |
3616 | .ndo_fdb_del = rocker_port_fdb_del, | 3688 | .ndo_fdb_del = rocker_port_fdb_del, |
3689 | .ndo_fdb_dump = rocker_port_fdb_dump, | ||
3617 | .ndo_switch_parent_id_get = rocker_port_switch_parent_id_get, | 3690 | .ndo_switch_parent_id_get = rocker_port_switch_parent_id_get, |
3618 | .ndo_switch_port_stp_update = rocker_port_switch_port_stp_update, | 3691 | .ndo_switch_port_stp_update = rocker_port_switch_port_stp_update, |
3619 | }; | 3692 | }; |