diff options
author | Vlad Yasevich <vyasevic@redhat.com> | 2014-05-16 09:59:17 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-05-16 17:06:33 -0400 |
commit | 8db24af71b31690a30ad371b35936fa10e547ee7 (patch) | |
tree | 174363a474eba5c02f24a6fb865a5b337eb5be6b /net/bridge/br_fdb.c | |
parent | e028e4b8dc93be7bc3ff9e0b94cb68d7f104883b (diff) |
bridge: Add functionality to sync static fdb entries to hw
Add code that allows static fdb entires to be synced to the
hw list for a specified port. This will be used later to
program ports that can function in non-promiscuous mode.
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Vlad Yasevich <vyasevic@redhat.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/bridge/br_fdb.c')
-rw-r--r-- | net/bridge/br_fdb.c | 56 |
1 files changed, 56 insertions, 0 deletions
diff --git a/net/bridge/br_fdb.c b/net/bridge/br_fdb.c index 9203d5a1943f..fe124e59a344 100644 --- a/net/bridge/br_fdb.c +++ b/net/bridge/br_fdb.c | |||
@@ -874,3 +874,59 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[], | |||
874 | out: | 874 | out: |
875 | return err; | 875 | return err; |
876 | } | 876 | } |
877 | |||
878 | int br_fdb_sync_static(struct net_bridge *br, struct net_bridge_port *p) | ||
879 | { | ||
880 | struct net_bridge_fdb_entry *fdb, *tmp; | ||
881 | int i; | ||
882 | int err; | ||
883 | |||
884 | ASSERT_RTNL(); | ||
885 | |||
886 | for (i = 0; i < BR_HASH_SIZE; i++) { | ||
887 | hlist_for_each_entry(fdb, &br->hash[i], hlist) { | ||
888 | /* We only care for static entries */ | ||
889 | if (!fdb->is_static) | ||
890 | continue; | ||
891 | |||
892 | err = dev_uc_add(p->dev, fdb->addr.addr); | ||
893 | if (err) | ||
894 | goto rollback; | ||
895 | } | ||
896 | } | ||
897 | return 0; | ||
898 | |||
899 | rollback: | ||
900 | for (i = 0; i < BR_HASH_SIZE; i++) { | ||
901 | hlist_for_each_entry(tmp, &br->hash[i], hlist) { | ||
902 | /* If we reached the fdb that failed, we can stop */ | ||
903 | if (tmp == fdb) | ||
904 | break; | ||
905 | |||
906 | /* We only care for static entries */ | ||
907 | if (!tmp->is_static) | ||
908 | continue; | ||
909 | |||
910 | dev_uc_del(p->dev, tmp->addr.addr); | ||
911 | } | ||
912 | } | ||
913 | return err; | ||
914 | } | ||
915 | |||
916 | void br_fdb_unsync_static(struct net_bridge *br, struct net_bridge_port *p) | ||
917 | { | ||
918 | struct net_bridge_fdb_entry *fdb; | ||
919 | int i; | ||
920 | |||
921 | ASSERT_RTNL(); | ||
922 | |||
923 | for (i = 0; i < BR_HASH_SIZE; i++) { | ||
924 | hlist_for_each_entry_rcu(fdb, &br->hash[i], hlist) { | ||
925 | /* We only care for static entries */ | ||
926 | if (!fdb->is_static) | ||
927 | continue; | ||
928 | |||
929 | dev_uc_del(p->dev, fdb->addr.addr); | ||
930 | } | ||
931 | } | ||
932 | } | ||