Skip to content

Commit 390bcf1

Browse files
committed
Merge: CNB97: bridge: update bridge core to upstream v6.15.
MR: https://gitlab.com/redhat/centos-stream/src/kernel/centos-stream-9/-/merge_requests/7144 JIRA: https://issues.redhat.com/browse/RHEL-75594 update bridge core to upstream v6.15. Signed-off-by: Mohammad Heib <mheib@redhat.com> Approved-by: Hangbin Liu <haliu@redhat.com> Approved-by: Michal Schmidt <mschmidt@redhat.com> Approved-by: CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> Merged-by: Augusto Caringi <acaringi@redhat.com>
2 parents 4b322bc + b3186b0 commit 390bcf1

28 files changed

+981
-122
lines changed

include/linux/if_bridge.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,9 @@ struct br_ip_list {
6565
#define BR_DEFAULT_AGEING_TIME (300 * HZ)
6666

6767
struct net_bridge;
68-
void brioctl_set(int (*hook)(struct net *net, struct net_bridge *br,
69-
unsigned int cmd, struct ifreq *ifr,
68+
void brioctl_set(int (*hook)(struct net *net, unsigned int cmd,
7069
void __user *uarg));
71-
int br_ioctl_call(struct net *net, struct net_bridge *br, unsigned int cmd,
72-
struct ifreq *ifr, void __user *uarg);
70+
int br_ioctl_call(struct net *net, unsigned int cmd, void __user *uarg);
7371

7472
#if IS_ENABLED(CONFIG_BRIDGE) && IS_ENABLED(CONFIG_BRIDGE_IGMP_SNOOPING)
7573
int br_multicast_list_adjacent(struct net_device *dev,

include/uapi/linux/if_bridge.h

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -699,10 +699,11 @@ struct br_mdb_entry {
699699
#define MDB_TEMPORARY 0
700700
#define MDB_PERMANENT 1
701701
__u8 state;
702-
#define MDB_FLAGS_OFFLOAD (1 << 0)
703-
#define MDB_FLAGS_FAST_LEAVE (1 << 1)
704-
#define MDB_FLAGS_STAR_EXCL (1 << 2)
705-
#define MDB_FLAGS_BLOCKED (1 << 3)
702+
#define MDB_FLAGS_OFFLOAD (1 << 0)
703+
#define MDB_FLAGS_FAST_LEAVE (1 << 1)
704+
#define MDB_FLAGS_STAR_EXCL (1 << 2)
705+
#define MDB_FLAGS_BLOCKED (1 << 3)
706+
#define MDB_FLAGS_OFFLOAD_FAILED (1 << 4)
706707
__u8 flags;
707708
__u16 vid;
708709
struct {
@@ -830,6 +831,7 @@ enum br_boolopt_id {
830831
BR_BOOLOPT_NO_LL_LEARN,
831832
BR_BOOLOPT_MCAST_VLAN_SNOOPING,
832833
BR_BOOLOPT_MST_ENABLE,
834+
BR_BOOLOPT_MDB_OFFLOAD_FAIL_NOTIFICATION,
833835
BR_BOOLOPT_MAX
834836
};
835837

net/bridge/br.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
5151
}
5252
}
5353

54+
if (is_vlan_dev(dev)) {
55+
struct net_device *real_dev = vlan_dev_real_dev(dev);
56+
57+
if (netif_is_bridge_master(real_dev))
58+
br_vlan_vlan_upper_event(real_dev, dev, event);
59+
}
60+
5461
/* not a port of a bridge */
5562
p = br_port_get_rtnl(dev);
5663
if (!p)
@@ -277,6 +284,9 @@ int br_boolopt_toggle(struct net_bridge *br, enum br_boolopt_id opt, bool on,
277284
case BR_BOOLOPT_MST_ENABLE:
278285
err = br_mst_set_enabled(br, on, extack);
279286
break;
287+
case BR_BOOLOPT_MDB_OFFLOAD_FAIL_NOTIFICATION:
288+
br_opt_toggle(br, BROPT_MDB_OFFLOAD_FAIL_NOTIFICATION, on);
289+
break;
280290
default:
281291
/* shouldn't be called with unsupported options */
282292
WARN_ON(1);
@@ -295,6 +305,8 @@ int br_boolopt_get(const struct net_bridge *br, enum br_boolopt_id opt)
295305
return br_opt_get(br, BROPT_MCAST_VLAN_SNOOPING_ENABLED);
296306
case BR_BOOLOPT_MST_ENABLE:
297307
return br_opt_get(br, BROPT_MST_ENABLED);
308+
case BR_BOOLOPT_MDB_OFFLOAD_FAIL_NOTIFICATION:
309+
return br_opt_get(br, BROPT_MDB_OFFLOAD_FAIL_NOTIFICATION);
298310
default:
299311
/* shouldn't be called with unsupported options */
300312
WARN_ON(1);

net/bridge/br_arp_nd_proxy.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,9 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
160160
if (br_opt_get(br, BROPT_NEIGH_SUPPRESS_ENABLED)) {
161161
if (br_is_neigh_suppress_enabled(p, vid))
162162
return;
163+
if (is_unicast_ether_addr(eth_hdr(skb)->h_dest) &&
164+
parp->ar_op == htons(ARPOP_REQUEST))
165+
return;
163166
if (parp->ar_op != htons(ARPOP_RREQUEST) &&
164167
parp->ar_op != htons(ARPOP_RREPLY) &&
165168
(ipv4_is_zeronet(sip) || sip == tip)) {
@@ -229,7 +232,7 @@ void br_do_proxy_suppress_arp(struct sk_buff *skb, struct net_bridge *br,
229232
#endif
230233

231234
#if IS_ENABLED(CONFIG_IPV6)
232-
struct nd_msg *br_is_nd_neigh_msg(struct sk_buff *skb, struct nd_msg *msg)
235+
struct nd_msg *br_is_nd_neigh_msg(const struct sk_buff *skb, struct nd_msg *msg)
233236
{
234237
struct nd_msg *m;
235238

@@ -410,6 +413,10 @@ void br_do_suppress_nd(struct sk_buff *skb, struct net_bridge *br,
410413
if (br_is_neigh_suppress_enabled(p, vid))
411414
return;
412415

416+
if (is_unicast_ether_addr(eth_hdr(skb)->h_dest) &&
417+
msg->icmph.icmp6_type == NDISC_NEIGHBOUR_SOLICITATION)
418+
return;
419+
413420
if (msg->icmph.icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT &&
414421
!msg->icmph.icmp6_solicited) {
415422
/* prevent flooding to neigh suppress ports */

net/bridge/br_fdb.c

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1329,7 +1329,6 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
13291329
{
13301330
struct net_bridge_vlan_group *vg;
13311331
struct net_bridge_port *p = NULL;
1332-
struct net_bridge_vlan *v;
13331332
struct net_bridge *br;
13341333
int err;
13351334

@@ -1348,14 +1347,11 @@ int br_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
13481347
}
13491348

13501349
if (vid) {
1351-
v = br_vlan_find(vg, vid);
1352-
if (!v) {
1353-
pr_info("bridge: RTM_DELNEIGH with unconfigured vlan %d on %s\n", vid, dev->name);
1354-
return -EINVAL;
1355-
}
13561350

13571351
err = __br_fdb_delete(br, p, addr, vid, notified);
13581352
} else {
1353+
struct net_bridge_vlan *v;
1354+
13591355
err = -ENOENT;
13601356
err &= __br_fdb_delete(br, p, addr, 0, notified);
13611357
if (!vg || !vg->num_vlans)

net/bridge/br_input.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,8 @@ int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb
189189
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
190190
br_multicast_querier_exists(brmctx, eth_hdr(skb), mdst)) {
191191
if ((mdst && mdst->host_joined) ||
192-
br_multicast_is_router(brmctx, skb)) {
192+
br_multicast_is_router(brmctx, skb) ||
193+
br->dev->flags & IFF_ALLMULTI) {
193194
local_rcv = true;
194195
DEV_STATS_INC(br->dev, multicast);
195196
}

net/bridge/br_ioctl.c

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -394,10 +394,26 @@ static int old_deviceless(struct net *net, void __user *data)
394394
return -EOPNOTSUPP;
395395
}
396396

397-
int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
398-
struct ifreq *ifr, void __user *uarg)
397+
int br_ioctl_stub(struct net *net, unsigned int cmd, void __user *uarg)
399398
{
400399
int ret = -EOPNOTSUPP;
400+
struct ifreq ifr;
401+
402+
if (cmd == SIOCBRADDIF || cmd == SIOCBRDELIF) {
403+
void __user *data;
404+
char *colon;
405+
406+
if (!ns_capable(net->user_ns, CAP_NET_ADMIN))
407+
return -EPERM;
408+
409+
if (get_user_ifreq(&ifr, &data, uarg))
410+
return -EFAULT;
411+
412+
ifr.ifr_name[IFNAMSIZ - 1] = 0;
413+
colon = strchr(ifr.ifr_name, ':');
414+
if (colon)
415+
*colon = 0;
416+
}
401417

402418
rtnl_lock();
403419

@@ -430,7 +446,21 @@ int br_ioctl_stub(struct net *net, struct net_bridge *br, unsigned int cmd,
430446
break;
431447
case SIOCBRADDIF:
432448
case SIOCBRDELIF:
433-
ret = add_del_if(br, ifr->ifr_ifindex, cmd == SIOCBRADDIF);
449+
{
450+
struct net_device *dev;
451+
452+
dev = __dev_get_by_name(net, ifr.ifr_name);
453+
if (!dev || !netif_device_present(dev)) {
454+
ret = -ENODEV;
455+
break;
456+
}
457+
if (!netif_is_bridge_master(dev)) {
458+
ret = -EOPNOTSUPP;
459+
break;
460+
}
461+
462+
ret = add_del_if(netdev_priv(dev), ifr.ifr_ifindex, cmd == SIOCBRADDIF);
463+
}
434464
break;
435465
}
436466

net/bridge/br_mdb.c

Lines changed: 24 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ static void __mdb_entry_fill_flags(struct br_mdb_entry *e, unsigned char flags)
144144
e->flags |= MDB_FLAGS_STAR_EXCL;
145145
if (flags & MDB_PG_FLAGS_BLOCKED)
146146
e->flags |= MDB_FLAGS_BLOCKED;
147+
if (flags & MDB_PG_FLAGS_OFFLOAD_FAILED)
148+
e->flags |= MDB_FLAGS_OFFLOAD_FAILED;
147149
}
148150

149151
static void __mdb_entry_to_br_ip(struct br_mdb_entry *entry, struct br_ip *ip,
@@ -517,16 +519,17 @@ static size_t rtnl_mdb_nlmsg_size(const struct net_bridge_port_group *pg)
517519
rtnl_mdb_nlmsg_pg_size(pg);
518520
}
519521

520-
void br_mdb_notify(struct net_device *dev,
521-
struct net_bridge_mdb_entry *mp,
522-
struct net_bridge_port_group *pg,
523-
int type)
522+
static void __br_mdb_notify(struct net_device *dev,
523+
struct net_bridge_mdb_entry *mp,
524+
struct net_bridge_port_group *pg,
525+
int type, bool notify_switchdev)
524526
{
525527
struct net *net = dev_net(dev);
526528
struct sk_buff *skb;
527529
int err = -ENOBUFS;
528530

529-
br_switchdev_mdb_notify(dev, mp, pg, type);
531+
if (notify_switchdev)
532+
br_switchdev_mdb_notify(dev, mp, pg, type);
530533

531534
skb = nlmsg_new(rtnl_mdb_nlmsg_size(pg), GFP_ATOMIC);
532535
if (!skb)
@@ -544,6 +547,21 @@ void br_mdb_notify(struct net_device *dev,
544547
rtnl_set_sk_err(net, RTNLGRP_MDB, err);
545548
}
546549

550+
void br_mdb_notify(struct net_device *dev,
551+
struct net_bridge_mdb_entry *mp,
552+
struct net_bridge_port_group *pg,
553+
int type)
554+
{
555+
__br_mdb_notify(dev, mp, pg, type, true);
556+
}
557+
558+
void br_mdb_flag_change_notify(struct net_device *dev,
559+
struct net_bridge_mdb_entry *mp,
560+
struct net_bridge_port_group *pg)
561+
{
562+
__br_mdb_notify(dev, mp, pg, RTM_NEWMDB, false);
563+
}
564+
547565
static int nlmsg_populate_rtr_fill(struct sk_buff *skb,
548566
struct net_device *dev,
549567
int ifindex, u16 vid, u32 pid,
@@ -1040,7 +1058,7 @@ static int br_mdb_add_group(const struct br_mdb_config *cfg,
10401058

10411059
/* host join */
10421060
if (!port) {
1043-
if (mp->host_joined) {
1061+
if (mp->host_joined && !(cfg->nlflags & NLM_F_REPLACE)) {
10441062
NL_SET_ERR_MSG_MOD(extack, "Group is already joined by host");
10451063
return -EEXIST;
10461064
}

net/bridge/br_mst.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,10 +80,10 @@ static void br_mst_vlan_set_state(struct net_bridge_vlan_group *vg,
8080
if (br_vlan_get_state(v) == state)
8181
return;
8282

83-
br_vlan_set_state(v, state);
84-
8583
if (v->vid == vg->pvid)
8684
br_vlan_set_pvid_state(vg, state);
85+
86+
br_vlan_set_state(v, state);
8787
}
8888

8989
int br_mst_set_state(struct net_bridge_port *p, u16 msti, u8 state,

0 commit comments

Comments
 (0)