History

net: bridge: Receive notification about successful FDB offload

When a new static FDB is added to the bridge a notification is sent to the driver for offload. In case of successful offload the driver should notify the bridge back, which in turn should mark the FDB as offloaded. Currently, externally learned is equivalent for being offloaded which is not correct due to the fact that FDBs which are added from user-space are also marked as externally learned. In order to specify if an FDB was successfully offloaded a new flag is introduced.

Arkadi Sharshevsky committed 9 years ago

Commit 9fe8bce1 parent 6b26b515 files · +37 −3Browse files

Unified · Split

5 files
  1. include/net/switchdev.h +1 −0
  2. include/uapi/linux/neighbour.h +1 −0
  3. net/bridge/br.c +10 −1
  4. net/bridge/br_fdb.c +21 −1
  5. net/bridge/br_private.h +4 −1
include/net/switchdev.h+1−0
@@ -159,6 +159,7 @@ enum switchdev_notifier_type { · 158 unmodified lines
159 SWITCHDEV_FDB_DEL_TO_BRIDGE,159 SWITCHDEV_FDB_DEL_TO_BRIDGE,
160 SWITCHDEV_FDB_ADD_TO_DEVICE,160 SWITCHDEV_FDB_ADD_TO_DEVICE,
161 SWITCHDEV_FDB_DEL_TO_DEVICE,161 SWITCHDEV_FDB_DEL_TO_DEVICE,
162 SWITCHDEV_FDB_OFFLOADED,
162};163};
163 164
164struct switchdev_notifier_info {165struct switchdev_notifier_info {
include/uapi/linux/neighbour.h+1−0
@@ -41,6 +41,7 @@ enum { · 40 unmodified lines
41#define NTF_MASTER 0x0441#define NTF_MASTER 0x04
42#define NTF_PROXY 0x08 /* == ATF_PUBL */42#define NTF_PROXY 0x08 /* == ATF_PUBL */
43#define NTF_EXT_LEARNED 0x1043#define NTF_EXT_LEARNED 0x10
44#define NTF_OFFLOADED 0x20
44#define NTF_ROUTER 0x8045#define NTF_ROUTER 0x80
45 46
46/*47/*
net/bridge/br.c+10−1
@@ -142,8 +142,12 @@ static int br_switchdev_event(struct notifier_block *unused, · 141 unmodified lines
142 fdb_info = ptr;142 fdb_info = ptr;
143 err = br_fdb_external_learn_add(br, p, fdb_info->addr,143 err = br_fdb_external_learn_add(br, p, fdb_info->addr,
144 fdb_info->vid);144 fdb_info->vid);
145 if (err)145 if (err) {
146 err = notifier_from_errno(err);146 err = notifier_from_errno(err);
147 break;
148 }
149 br_fdb_offloaded_set(br, p, fdb_info->addr,
150 fdb_info->vid);
147 break;151 break;
148 case SWITCHDEV_FDB_DEL_TO_BRIDGE:152 case SWITCHDEV_FDB_DEL_TO_BRIDGE:
149 fdb_info = ptr;153 fdb_info = ptr;
@@ -152,6 +156,11 @@ static int br_switchdev_event(struct notifier_block *unused, · 2 unmodified lines
152 if (err)156 if (err)
153 err = notifier_from_errno(err);157 err = notifier_from_errno(err);
154 break;158 break;
159 case SWITCHDEV_FDB_OFFLOADED:
160 fdb_info = ptr;
161 br_fdb_offloaded_set(br, p, fdb_info->addr,
162 fdb_info->vid);
163 break;
155 }164 }
156 165
157out:166out:
net/bridge/br_fdb.c+21−1
@@ -511,6 +511,7 @@ static struct net_bridge_fdb_entry *fdb_create(struct hlist_head *head, · 510 unmodified lines
511 fdb->is_static = is_static;511 fdb->is_static = is_static;
512 fdb->added_by_user = 0;512 fdb->added_by_user = 0;
513 fdb->added_by_external_learn = 0;513 fdb->added_by_external_learn = 0;
514 fdb->offloaded = 0;
514 fdb->updated = fdb->used = jiffies;515 fdb->updated = fdb->used = jiffies;
515 hlist_add_head_rcu(&fdb->hlist, head);516 hlist_add_head_rcu(&fdb->hlist, head);
516 }517 }
@@ -647,11 +648,16 @@ static int fdb_fill_info(struct sk_buff *skb, const struct net_bridge *br, · 130 unmodified lines
647 ndm->ndm_family = AF_BRIDGE;648 ndm->ndm_family = AF_BRIDGE;
648 ndm->ndm_pad1 = 0;649 ndm->ndm_pad1 = 0;
649 ndm->ndm_pad2 = 0;650 ndm->ndm_pad2 = 0;
650 ndm->ndm_flags = fdb->added_by_external_learn ? NTF_EXT_LEARNED : 0;651 ndm->ndm_flags = 0;
651 ndm->ndm_type = 0;652 ndm->ndm_type = 0;
652 ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;653 ndm->ndm_ifindex = fdb->dst ? fdb->dst->dev->ifindex : br->dev->ifindex;
653 ndm->ndm_state = fdb_to_nud(br, fdb);654 ndm->ndm_state = fdb_to_nud(br, fdb);
654 655
656 if (fdb->offloaded)
657 ndm->ndm_flags |= NTF_OFFLOADED;
658 if (fdb->added_by_external_learn)
659 ndm->ndm_flags |= NTF_EXT_LEARNED;
660
655 if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr))661 if (nla_put(skb, NDA_LLADDR, ETH_ALEN, &fdb->addr))
656 goto nla_put_failure;662 goto nla_put_failure;
657 if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex))663 if (nla_put_u32(skb, NDA_MASTER, br->dev->ifindex))
@@ -1123,3 +1129,17 @@ int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p, · 465 unmodified lines
1123 1129
1124 return err;1130 return err;
1125}1131}
1132
1133void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
1134 const unsigned char *addr, u16 vid)
1135{
1136 struct net_bridge_fdb_entry *fdb;
1137
1138 spin_lock_bh(&br->hash_lock);
1139
1140 fdb = br_fdb_find(br, addr, vid);
1141 if (fdb)
1142 fdb->offloaded = 1;
1143
1144 spin_unlock_bh(&br->hash_lock);
1145}
net/bridge/br_private.h+4−1
@@ -169,7 +169,8 @@ struct net_bridge_fdb_entry { · 168 unmodified lines
169 unsigned char is_local:1,169 unsigned char is_local:1,
170 is_static:1,170 is_static:1,
171 added_by_user:1,171 added_by_user:1,
172 added_by_external_learn:1;172 added_by_external_learn:1,
173 offloaded:1;
173 174
174 /* write-heavy members should not affect lookups */175 /* write-heavy members should not affect lookups */
175 unsigned long updated ____cacheline_aligned_in_smp;176 unsigned long updated ____cacheline_aligned_in_smp;
@@ -536,6 +537,8 @@ int br_fdb_external_learn_add(struct net_bridge *br, struct net_bridge_port *p, · 360 unmodified lines
536 const unsigned char *addr, u16 vid);537 const unsigned char *addr, u16 vid);
537int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,538int br_fdb_external_learn_del(struct net_bridge *br, struct net_bridge_port *p,
538 const unsigned char *addr, u16 vid);539 const unsigned char *addr, u16 vid);
540void br_fdb_offloaded_set(struct net_bridge *br, struct net_bridge_port *p,
541 const unsigned char *addr, u16 vid);
539 542
540/* br_forward.c */543/* br_forward.c */
541enum br_pkt_type {544enum br_pkt_type {