History

net: bridge: mcast: add rt_protocol field to the port group struct

We need to be able to differentiate between pg entries created by user-space and the kernel when we start generating S,G entries for IGMPv3/MLDv2's fast path. User-space entries are created by default as RTPROT_STATIC and the kernel entries are RTPROT_KERNEL. Later we can allow user-space to provide the entry rt_protocol so we can differentiate between who added the entries specifically (e.g. clag, admin, frr etc).

Nikolay Aleksandrov committed 6 years ago

Commit 8f8cb771 parent 7d07a684 files · +34 −19Browse files

Unified · Split

4 files
  1. include/uapi/linux/if_bridge.h +1 −0
  2. net/bridge/br_mdb.c +26 −16
  3. net/bridge/br_multicast.c +5 −2
  4. net/bridge/br_private.h +2 −1
include/uapi/linux/if_bridge.h+1−0
@@ -458,6 +458,7 @@ enum { · 457 unmodified lines
458458 MDBA_MDB_EATTR_SRC_LIST,
459459 MDBA_MDB_EATTR_GROUP_MODE,
460460 MDBA_MDB_EATTR_SOURCE,
461+ MDBA_MDB_EATTR_RTPROT,
461462 __MDBA_MDB_EATTR_MAX
462463 };
463464 #define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)
net/bridge/br_mdb.c+26−16
@@ -184,6 +184,7 @@ static int __mdb_fill_info(struct sk_buff *skb, · 183 unmodified lines
184184 MDBA_MDB_EATTR_TIMER,
185185 br_timer_value(mtimer)))
186186 goto nest_err;
187+
187188 switch (mp->addr.proto) {
188189 case htons(ETH_P_IP):
189190 dump_srcs_mode = !!(mp->br->multicast_igmp_version == 3);
@@ -206,10 +207,15 @@ static int __mdb_fill_info(struct sk_buff *skb, · 16 unmodified lines
206207 break;
207208 #endif
208209 }
209− if (p && dump_srcs_mode &&
210− (__mdb_fill_srcs(skb, p) ||
211− nla_put_u8(skb, MDBA_MDB_EATTR_GROUP_MODE, p->filter_mode)))
212− goto nest_err;
210+ if (p) {
211+ if (nla_put_u8(skb, MDBA_MDB_EATTR_RTPROT, p->rt_protocol))
212+ goto nest_err;
213+ if (dump_srcs_mode &&
214+ (__mdb_fill_srcs(skb, p) ||
215+ nla_put_u8(skb, MDBA_MDB_EATTR_GROUP_MODE,
216+ p->filter_mode)))
217+ goto nest_err;
218+ }
213219 nla_nest_end(skb, nest_ent);
214220
215221 return 0;
@@ -414,6 +420,9 @@ static size_t rtnl_mdb_nlmsg_size(struct net_bridge_port_group *pg) · 198 unmodified lines
414420 if (!pg)
415421 goto out;
416422
423+ /* MDBA_MDB_EATTR_RTPROT */
424+ nlmsg_size += nla_total_size(sizeof(u8));
425+
417426 switch (pg->addr.proto) {
418427 case htons(ETH_P_IP):
419428 /* MDBA_MDB_EATTR_SOURCE */
@@ -809,16 +818,20 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, · 389 unmodified lines
809818 }
810819
811820 static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,
812− struct br_ip *group, struct br_mdb_entry *entry,
821+ struct br_mdb_entry *entry,
822+ struct nlattr **mdb_attrs,
813823 struct netlink_ext_ack *extack)
814824 {
815825 struct net_bridge_mdb_entry *mp;
816826 struct net_bridge_port_group *p;
817827 struct net_bridge_port_group __rcu **pp;
818828 unsigned long now = jiffies;
829+ struct br_ip group;
819830 u8 filter_mode;
820831 int err;
821832
833+ __mdb_entry_to_br_ip(entry, &group, mdb_attrs);
834+
822835 /* host join errors which can happen before creating the group */
823836 if (!port) {
824837 /* don't allow any flags for host-joined groups */
@@ -826,15 +839,15 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, · 1 unmodified line
826839 NL_SET_ERR_MSG_MOD(extack, "Flags are not allowed for host groups");
827840 return -EINVAL;
828841 }
829− if (!br_multicast_is_star_g(group)) {
842+ if (!br_multicast_is_star_g(&group)) {
830843 NL_SET_ERR_MSG_MOD(extack, "Groups with sources cannot be manually host joined");
831844 return -EINVAL;
832845 }
833846 }
834847
835− mp = br_mdb_ip_get(br, group);
848+ mp = br_mdb_ip_get(br, &group);
836849 if (!mp) {
837− mp = br_multicast_new_group(br, group);
850+ mp = br_multicast_new_group(br, &group);
838851 err = PTR_ERR_OR_ZERO(mp);
839852 if (err)
840853 return err;
@@ -864,11 +877,11 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, · 23 unmodified lines
864877 break;
865878 }
866879
867− filter_mode = br_multicast_is_star_g(group) ? MCAST_EXCLUDE :
868− MCAST_INCLUDE;
880+ filter_mode = br_multicast_is_star_g(&group) ? MCAST_EXCLUDE :
881+ MCAST_INCLUDE;
869882
870− p = br_multicast_new_port_group(port, group, *pp, entry->state, NULL,
871− filter_mode);
883+ p = br_multicast_new_port_group(port, &group, *pp, entry->state, NULL,
884+ filter_mode, RTPROT_STATIC);
872885 if (unlikely(!p)) {
873886 NL_SET_ERR_MSG_MOD(extack, "Couldn't allocate new port group");
874887 return -ENOMEM;
@@ -887,13 +900,10 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, · 12 unmodified lines
887900 struct nlattr **mdb_attrs,
888901 struct netlink_ext_ack *extack)
889902 {
890− struct br_ip ip;
891903 int ret;
892904
893− __mdb_entry_to_br_ip(entry, &ip, mdb_attrs);
894−
895905 spin_lock_bh(&br->multicast_lock);
896− ret = br_mdb_add_group(br, p, &ip, entry, extack);
906+ ret = br_mdb_add_group(br, p, entry, mdb_attrs, extack);
897907 spin_unlock_bh(&br->multicast_lock);
898908
899909 return ret;
net/bridge/br_multicast.c+5−2
@@ -795,7 +795,8 @@ struct net_bridge_port_group *br_multicast_new_port_group( · 794 unmodified lines
795795 struct net_bridge_port_group __rcu *next,
796796 unsigned char flags,
797797 const unsigned char *src,
798− u8 filter_mode)
798+ u8 filter_mode,
799+ u8 rt_protocol)
799800 {
800801 struct net_bridge_port_group *p;
801802
@@ -807,6 +808,7 @@ struct net_bridge_port_group *br_multicast_new_port_group( · 5 unmodified lines
807808 p->port = port;
808809 p->flags = flags;
809810 p->filter_mode = filter_mode;
811+ p->rt_protocol = rt_protocol;
810812 p->mcast_gc.destroy = br_multicast_destroy_port_group;
811813 INIT_HLIST_HEAD(&p->src_list);
812814 rcu_assign_pointer(p->next, next);
@@ -892,7 +894,8 @@ static int br_multicast_add_group(struct net_bridge *br, · 79 unmodified lines
892894 break;
893895 }
894896
895− p = br_multicast_new_port_group(port, group, *pp, 0, src, filter_mode);
897+ p = br_multicast_new_port_group(port, group, *pp, 0, src, filter_mode,
898+ RTPROT_KERNEL);
896899 if (unlikely(!p))
897900 goto err;
898901 rcu_assign_pointer(*pp, p);
net/bridge/br_private.h+2−1
@@ -246,6 +246,7 @@ struct net_bridge_port_group { · 245 unmodified lines
246246 unsigned char flags;
247247 unsigned char filter_mode;
248248 unsigned char grp_query_rexmit_cnt;
249+ unsigned char rt_protocol;
249250
250251 struct hlist_head src_list;
251252 unsigned int src_ents;
@@ -804,7 +805,7 @@ struct net_bridge_port_group * · 552 unmodified lines
804805 br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
805806 struct net_bridge_port_group __rcu *next,
806807 unsigned char flags, const unsigned char *src,
807− u8 filter_mode);
808+ u8 filter_mode, u8 rt_protocol);
808809 int br_mdb_hash_init(struct net_bridge *br);
809810 void br_mdb_hash_fini(struct net_bridge *br);
810811 void br_mdb_notify(struct net_device *dev, struct net_bridge_mdb_entry *mp,

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t