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
458 MDBA_MDB_EATTR_SRC_LIST,458 MDBA_MDB_EATTR_SRC_LIST,
459 MDBA_MDB_EATTR_GROUP_MODE,459 MDBA_MDB_EATTR_GROUP_MODE,
460 MDBA_MDB_EATTR_SOURCE,460 MDBA_MDB_EATTR_SOURCE,
461 MDBA_MDB_EATTR_RTPROT,
461 __MDBA_MDB_EATTR_MAX462 __MDBA_MDB_EATTR_MAX
462};463};
463#define MDBA_MDB_EATTR_MAX (__MDBA_MDB_EATTR_MAX - 1)464#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
184 MDBA_MDB_EATTR_TIMER,184 MDBA_MDB_EATTR_TIMER,
185 br_timer_value(mtimer)))185 br_timer_value(mtimer)))
186 goto nest_err;186 goto nest_err;
187
187 switch (mp->addr.proto) {188 switch (mp->addr.proto) {
188 case htons(ETH_P_IP):189 case htons(ETH_P_IP):
189 dump_srcs_mode = !!(mp->br->multicast_igmp_version == 3);190 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
206 break;207 break;
207#endif208#endif
208 }209 }
209 if (p && dump_srcs_mode &&210 if (p) {
210 (__mdb_fill_srcs(skb, p) ||211 if (nla_put_u8(skb, MDBA_MDB_EATTR_RTPROT, p->rt_protocol))
211 nla_put_u8(skb, MDBA_MDB_EATTR_GROUP_MODE, p->filter_mode)))212 goto nest_err;
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 }
213 nla_nest_end(skb, nest_ent);219 nla_nest_end(skb, nest_ent);
214 220
215 return 0;221 return 0;
@@ -414,6 +420,9 @@ static size_t rtnl_mdb_nlmsg_size(struct net_bridge_port_group *pg) · 198 unmodified lines
414 if (!pg)420 if (!pg)
415 goto out;421 goto out;
416 422
423 /* MDBA_MDB_EATTR_RTPROT */
424 nlmsg_size += nla_total_size(sizeof(u8));
425
417 switch (pg->addr.proto) {426 switch (pg->addr.proto) {
418 case htons(ETH_P_IP):427 case htons(ETH_P_IP):
419 /* MDBA_MDB_EATTR_SOURCE */428 /* MDBA_MDB_EATTR_SOURCE */
@@ -809,16 +818,20 @@ static int br_mdb_parse(struct sk_buff *skb, struct nlmsghdr *nlh, · 389 unmodified lines
809}818}
810 819
811static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port,820static 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,
813 struct netlink_ext_ack *extack)823 struct netlink_ext_ack *extack)
814{824{
815 struct net_bridge_mdb_entry *mp;825 struct net_bridge_mdb_entry *mp;
816 struct net_bridge_port_group *p;826 struct net_bridge_port_group *p;
817 struct net_bridge_port_group __rcu **pp;827 struct net_bridge_port_group __rcu **pp;
818 unsigned long now = jiffies;828 unsigned long now = jiffies;
829 struct br_ip group;
819 u8 filter_mode;830 u8 filter_mode;
820 int err;831 int err;
821 832
833 __mdb_entry_to_br_ip(entry, &group, mdb_attrs);
834
822 /* host join errors which can happen before creating the group */835 /* host join errors which can happen before creating the group */
823 if (!port) {836 if (!port) {
824 /* don't allow any flags for host-joined groups */837 /* 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
826 NL_SET_ERR_MSG_MOD(extack, "Flags are not allowed for host groups");839 NL_SET_ERR_MSG_MOD(extack, "Flags are not allowed for host groups");
827 return -EINVAL;840 return -EINVAL;
828 }841 }
829 if (!br_multicast_is_star_g(group)) {842 if (!br_multicast_is_star_g(&group)) {
830 NL_SET_ERR_MSG_MOD(extack, "Groups with sources cannot be manually host joined");843 NL_SET_ERR_MSG_MOD(extack, "Groups with sources cannot be manually host joined");
831 return -EINVAL;844 return -EINVAL;
832 }845 }
833 }846 }
834 847
835 mp = br_mdb_ip_get(br, group);848 mp = br_mdb_ip_get(br, &group);
836 if (!mp) {849 if (!mp) {
837 mp = br_multicast_new_group(br, group);850 mp = br_multicast_new_group(br, &group);
838 err = PTR_ERR_OR_ZERO(mp);851 err = PTR_ERR_OR_ZERO(mp);
839 if (err)852 if (err)
840 return err;853 return err;
@@ -864,11 +877,11 @@ static int br_mdb_add_group(struct net_bridge *br, struct net_bridge_port *port, · 23 unmodified lines
864 break;877 break;
865 }878 }
866 879
867 filter_mode = br_multicast_is_star_g(group) ? MCAST_EXCLUDE :880 filter_mode = br_multicast_is_star_g(&group) ? MCAST_EXCLUDE :
868 MCAST_INCLUDE;881 MCAST_INCLUDE;
869 882
870 p = br_multicast_new_port_group(port, group, *pp, entry->state, NULL,883 p = br_multicast_new_port_group(port, &group, *pp, entry->state, NULL,
871 filter_mode);884 filter_mode, RTPROT_STATIC);
872 if (unlikely(!p)) {885 if (unlikely(!p)) {
873 NL_SET_ERR_MSG_MOD(extack, "Couldn't allocate new port group");886 NL_SET_ERR_MSG_MOD(extack, "Couldn't allocate new port group");
874 return -ENOMEM;887 return -ENOMEM;
@@ -887,13 +900,10 @@ static int __br_mdb_add(struct net *net, struct net_bridge *br, · 12 unmodified lines
887 struct nlattr **mdb_attrs,900 struct nlattr **mdb_attrs,
888 struct netlink_ext_ack *extack)901 struct netlink_ext_ack *extack)
889{902{
890 struct br_ip ip;
891 int ret;903 int ret;
892 904
893 __mdb_entry_to_br_ip(entry, &ip, mdb_attrs);
894
895 spin_lock_bh(&br->multicast_lock);905 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);
897 spin_unlock_bh(&br->multicast_lock);907 spin_unlock_bh(&br->multicast_lock);
898 908
899 return ret;909 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
795 struct net_bridge_port_group __rcu *next,795 struct net_bridge_port_group __rcu *next,
796 unsigned char flags,796 unsigned char flags,
797 const unsigned char *src,797 const unsigned char *src,
798 u8 filter_mode)798 u8 filter_mode,
799 u8 rt_protocol)
799{800{
800 struct net_bridge_port_group *p;801 struct net_bridge_port_group *p;
801 802
@@ -807,6 +808,7 @@ struct net_bridge_port_group *br_multicast_new_port_group( · 5 unmodified lines
807 p->port = port;808 p->port = port;
808 p->flags = flags;809 p->flags = flags;
809 p->filter_mode = filter_mode;810 p->filter_mode = filter_mode;
811 p->rt_protocol = rt_protocol;
810 p->mcast_gc.destroy = br_multicast_destroy_port_group;812 p->mcast_gc.destroy = br_multicast_destroy_port_group;
811 INIT_HLIST_HEAD(&p->src_list);813 INIT_HLIST_HEAD(&p->src_list);
812 rcu_assign_pointer(p->next, next);814 rcu_assign_pointer(p->next, next);
@@ -892,7 +894,8 @@ static int br_multicast_add_group(struct net_bridge *br, · 79 unmodified lines
892 break;894 break;
893 }895 }
894 896
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);
896 if (unlikely(!p))899 if (unlikely(!p))
897 goto err;900 goto err;
898 rcu_assign_pointer(*pp, p);901 rcu_assign_pointer(*pp, p);
net/bridge/br_private.h+2−1
@@ -246,6 +246,7 @@ struct net_bridge_port_group { · 245 unmodified lines
246 unsigned char flags;246 unsigned char flags;
247 unsigned char filter_mode;247 unsigned char filter_mode;
248 unsigned char grp_query_rexmit_cnt;248 unsigned char grp_query_rexmit_cnt;
249 unsigned char rt_protocol;
249 250
250 struct hlist_head src_list;251 struct hlist_head src_list;
251 unsigned int src_ents;252 unsigned int src_ents;
@@ -804,7 +805,7 @@ struct net_bridge_port_group * · 552 unmodified lines
804br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,805br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group,
805 struct net_bridge_port_group __rcu *next,806 struct net_bridge_port_group __rcu *next,
806 unsigned char flags, const unsigned char *src,807 unsigned char flags, const unsigned char *src,
807 u8 filter_mode);808 u8 filter_mode, u8 rt_protocol);
808int br_mdb_hash_init(struct net_bridge *br);809int br_mdb_hash_init(struct net_bridge *br);
809void br_mdb_hash_fini(struct net_bridge *br);810void br_mdb_hash_fini(struct net_bridge *br);
810void br_mdb_notify(struct net_device *dev, struct net_bridge_mdb_entry *mp,811void 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