br_multicast.c (320424c7d44f54c18df9812fd7c45f6963524002) | br_multicast.c (9632233e7de8da43711bb7cd3e054af32fedcc38) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Bridge multicast support. 4 * 5 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 6 */ 7 8#include <linux/err.h> --- 37 unchanged lines hidden (view full) --- 46 .head_offset = offsetof(struct net_bridge_port_group, rhnode), 47 .key_offset = offsetof(struct net_bridge_port_group, key), 48 .key_len = sizeof(struct net_bridge_port_group_sg_key), 49 .automatic_shrinking = true, 50}; 51 52static void br_multicast_start_querier(struct net_bridge *br, 53 struct bridge_mcast_own_query *query); | 1// SPDX-License-Identifier: GPL-2.0-or-later 2/* 3 * Bridge multicast support. 4 * 5 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au> 6 */ 7 8#include <linux/err.h> --- 37 unchanged lines hidden (view full) --- 46 .head_offset = offsetof(struct net_bridge_port_group, rhnode), 47 .key_offset = offsetof(struct net_bridge_port_group, key), 48 .key_len = sizeof(struct net_bridge_port_group_sg_key), 49 .automatic_shrinking = true, 50}; 51 52static void br_multicast_start_querier(struct net_bridge *br, 53 struct bridge_mcast_own_query *query); |
54static void br_multicast_add_router(struct net_bridge *br, 55 struct net_bridge_port *port); | 54static void br_ip4_multicast_add_router(struct net_bridge *br, 55 struct net_bridge_port *port); |
56static void br_ip4_multicast_leave_group(struct net_bridge *br, 57 struct net_bridge_port *port, 58 __be32 group, 59 __u16 vid, 60 const unsigned char *src); 61static void br_multicast_port_group_rexmit(struct timer_list *t); 62 | 56static void br_ip4_multicast_leave_group(struct net_bridge *br, 57 struct net_bridge_port *port, 58 __be32 group, 59 __u16 vid, 60 const unsigned char *src); 61static void br_multicast_port_group_rexmit(struct timer_list *t); 62 |
63static void __del_port_router(struct net_bridge_port *p); | 63static void 64br_multicast_rport_del_notify(struct net_bridge_port *p, bool deleted); 65static void br_ip6_multicast_add_router(struct net_bridge *br, 66 struct net_bridge_port *port); |
64#if IS_ENABLED(CONFIG_IPV6) 65static void br_ip6_multicast_leave_group(struct net_bridge *br, 66 struct net_bridge_port *port, 67 const struct in6_addr *group, 68 __u16 vid, const unsigned char *src); 69#endif 70static struct net_bridge_port_group * 71__br_multicast_add_group(struct net_bridge *br, --- 1277 unchanged lines hidden (view full) --- 1349 br_group.vid = vid; 1350 filter_mode = mldv1 ? MCAST_EXCLUDE : MCAST_INCLUDE; 1351 1352 return br_multicast_add_group(br, port, &br_group, src, filter_mode, 1353 mldv1); 1354} 1355#endif 1356 | 67#if IS_ENABLED(CONFIG_IPV6) 68static void br_ip6_multicast_leave_group(struct net_bridge *br, 69 struct net_bridge_port *port, 70 const struct in6_addr *group, 71 __u16 vid, const unsigned char *src); 72#endif 73static struct net_bridge_port_group * 74__br_multicast_add_group(struct net_bridge *br, --- 1277 unchanged lines hidden (view full) --- 1352 br_group.vid = vid; 1353 filter_mode = mldv1 ? MCAST_EXCLUDE : MCAST_INCLUDE; 1354 1355 return br_multicast_add_group(br, port, &br_group, src, filter_mode, 1356 mldv1); 1357} 1358#endif 1359 |
1357static void br_multicast_router_expired(struct timer_list *t) | 1360static bool br_multicast_rport_del(struct hlist_node *rlist) |
1358{ | 1361{ |
1359 struct net_bridge_port *port = 1360 from_timer(port, t, multicast_router_timer); 1361 struct net_bridge *br = port->br; | 1362 if (hlist_unhashed(rlist)) 1363 return false; |
1362 | 1364 |
1365 hlist_del_init_rcu(rlist); 1366 return true; 1367} 1368 1369static bool br_ip4_multicast_rport_del(struct net_bridge_port *p) 1370{ 1371 return br_multicast_rport_del(&p->multicast_ctx.ip4_rlist); 1372} 1373 1374static bool br_ip6_multicast_rport_del(struct net_bridge_port *p) 1375{ 1376#if IS_ENABLED(CONFIG_IPV6) 1377 return br_multicast_rport_del(&p->multicast_ctx.ip6_rlist); 1378#else 1379 return false; 1380#endif 1381} 1382 1383static void br_multicast_router_expired(struct net_bridge_mcast_port *pmctx, 1384 struct timer_list *t, 1385 struct hlist_node *rlist) 1386{ 1387 struct net_bridge *br = pmctx->port->br; 1388 bool del; 1389 |
|
1363 spin_lock(&br->multicast_lock); | 1390 spin_lock(&br->multicast_lock); |
1364 if (port->multicast_router == MDB_RTR_TYPE_DISABLED || 1365 port->multicast_router == MDB_RTR_TYPE_PERM || 1366 timer_pending(&port->multicast_router_timer)) | 1391 if (pmctx->multicast_router == MDB_RTR_TYPE_DISABLED || 1392 pmctx->multicast_router == MDB_RTR_TYPE_PERM || 1393 timer_pending(t)) |
1367 goto out; 1368 | 1394 goto out; 1395 |
1369 __del_port_router(port); | 1396 del = br_multicast_rport_del(rlist); 1397 br_multicast_rport_del_notify(pmctx->port, del); |
1370out: 1371 spin_unlock(&br->multicast_lock); 1372} 1373 | 1398out: 1399 spin_unlock(&br->multicast_lock); 1400} 1401 |
1402static void br_ip4_multicast_router_expired(struct timer_list *t) 1403{ 1404 struct net_bridge_mcast_port *pmctx = from_timer(pmctx, t, 1405 ip4_mc_router_timer); 1406 1407 br_multicast_router_expired(pmctx, t, &pmctx->ip4_rlist); 1408} 1409 1410#if IS_ENABLED(CONFIG_IPV6) 1411static void br_ip6_multicast_router_expired(struct timer_list *t) 1412{ 1413 struct net_bridge_mcast_port *pmctx = from_timer(pmctx, t, 1414 ip6_mc_router_timer); 1415 1416 br_multicast_router_expired(pmctx, t, &pmctx->ip6_rlist); 1417} 1418#endif 1419 |
|
1374static void br_mc_router_state_change(struct net_bridge *p, 1375 bool is_mc_router) 1376{ 1377 struct switchdev_attr attr = { 1378 .orig_dev = p->dev, 1379 .id = SWITCHDEV_ATTR_ID_BRIDGE_MROUTER, 1380 .flags = SWITCHDEV_F_DEFER, 1381 .u.mrouter = is_mc_router, 1382 }; 1383 1384 switchdev_port_attr_set(p->dev, &attr, NULL); 1385} 1386 | 1420static void br_mc_router_state_change(struct net_bridge *p, 1421 bool is_mc_router) 1422{ 1423 struct switchdev_attr attr = { 1424 .orig_dev = p->dev, 1425 .id = SWITCHDEV_ATTR_ID_BRIDGE_MROUTER, 1426 .flags = SWITCHDEV_F_DEFER, 1427 .u.mrouter = is_mc_router, 1428 }; 1429 1430 switchdev_port_attr_set(p->dev, &attr, NULL); 1431} 1432 |
1387static void br_multicast_local_router_expired(struct timer_list *t) | 1433static void br_multicast_local_router_expired(struct net_bridge *br, 1434 struct timer_list *timer) |
1388{ | 1435{ |
1389 struct net_bridge *br = from_timer(br, t, multicast_router_timer); 1390 | |
1391 spin_lock(&br->multicast_lock); 1392 if (br->multicast_router == MDB_RTR_TYPE_DISABLED || 1393 br->multicast_router == MDB_RTR_TYPE_PERM || | 1436 spin_lock(&br->multicast_lock); 1437 if (br->multicast_router == MDB_RTR_TYPE_DISABLED || 1438 br->multicast_router == MDB_RTR_TYPE_PERM || |
1394 timer_pending(&br->multicast_router_timer)) | 1439 br_ip4_multicast_is_router(br) || 1440 br_ip6_multicast_is_router(br)) |
1395 goto out; 1396 1397 br_mc_router_state_change(br, false); 1398out: 1399 spin_unlock(&br->multicast_lock); 1400} 1401 | 1441 goto out; 1442 1443 br_mc_router_state_change(br, false); 1444out: 1445 spin_unlock(&br->multicast_lock); 1446} 1447 |
1448static void br_ip4_multicast_local_router_expired(struct timer_list *t) 1449{ 1450 struct net_bridge *br = from_timer(br, t, ip4_mc_router_timer); 1451 1452 br_multicast_local_router_expired(br, t); 1453} 1454 1455#if IS_ENABLED(CONFIG_IPV6) 1456static void br_ip6_multicast_local_router_expired(struct timer_list *t) 1457{ 1458 struct net_bridge *br = from_timer(br, t, ip6_mc_router_timer); 1459 1460 br_multicast_local_router_expired(br, t); 1461} 1462#endif 1463 |
|
1402static void br_multicast_querier_expired(struct net_bridge *br, 1403 struct bridge_mcast_own_query *query) 1404{ 1405 spin_lock(&br->multicast_lock); 1406 if (!netif_running(br->dev) || !br_opt_get(br, BROPT_MULTICAST_ENABLED)) 1407 goto out; 1408 1409 br_multicast_start_querier(br, query); --- 80 unchanged lines hidden (view full) --- 1490 1491 if (!netif_running(br->dev) || 1492 !br_opt_get(br, BROPT_MULTICAST_ENABLED) || 1493 !br_opt_get(br, BROPT_MULTICAST_QUERIER)) 1494 return; 1495 1496 memset(&br_group.dst, 0, sizeof(br_group.dst)); 1497 | 1464static void br_multicast_querier_expired(struct net_bridge *br, 1465 struct bridge_mcast_own_query *query) 1466{ 1467 spin_lock(&br->multicast_lock); 1468 if (!netif_running(br->dev) || !br_opt_get(br, BROPT_MULTICAST_ENABLED)) 1469 goto out; 1470 1471 br_multicast_start_querier(br, query); --- 80 unchanged lines hidden (view full) --- 1552 1553 if (!netif_running(br->dev) || 1554 !br_opt_get(br, BROPT_MULTICAST_ENABLED) || 1555 !br_opt_get(br, BROPT_MULTICAST_QUERIER)) 1556 return; 1557 1558 memset(&br_group.dst, 0, sizeof(br_group.dst)); 1559 |
1498 if (port ? (own_query == &port->ip4_own_query) : | 1560 if (port ? (own_query == &port->multicast_ctx.ip4_own_query) : |
1499 (own_query == &br->ip4_own_query)) { 1500 other_query = &br->ip4_other_query; 1501 br_group.proto = htons(ETH_P_IP); 1502#if IS_ENABLED(CONFIG_IPV6) 1503 } else { 1504 other_query = &br->ip6_other_query; 1505 br_group.proto = htons(ETH_P_IPV6); 1506#endif --- 8 unchanged lines hidden (view full) --- 1515 time = jiffies; 1516 time += own_query->startup_sent < br->multicast_startup_query_count ? 1517 br->multicast_startup_query_interval : 1518 br->multicast_query_interval; 1519 mod_timer(&own_query->timer, time); 1520} 1521 1522static void | 1561 (own_query == &br->ip4_own_query)) { 1562 other_query = &br->ip4_other_query; 1563 br_group.proto = htons(ETH_P_IP); 1564#if IS_ENABLED(CONFIG_IPV6) 1565 } else { 1566 other_query = &br->ip6_other_query; 1567 br_group.proto = htons(ETH_P_IPV6); 1568#endif --- 8 unchanged lines hidden (view full) --- 1577 time = jiffies; 1578 time += own_query->startup_sent < br->multicast_startup_query_count ? 1579 br->multicast_startup_query_interval : 1580 br->multicast_query_interval; 1581 mod_timer(&own_query->timer, time); 1582} 1583 1584static void |
1523br_multicast_port_query_expired(struct net_bridge_port *port, | 1585br_multicast_port_query_expired(struct net_bridge_mcast_port *pmctx, |
1524 struct bridge_mcast_own_query *query) 1525{ | 1586 struct bridge_mcast_own_query *query) 1587{ |
1526 struct net_bridge *br = port->br; | 1588 struct net_bridge *br = pmctx->port->br; |
1527 1528 spin_lock(&br->multicast_lock); | 1589 1590 spin_lock(&br->multicast_lock); |
1529 if (port->state == BR_STATE_DISABLED || 1530 port->state == BR_STATE_BLOCKING) | 1591 if (pmctx->port->state == BR_STATE_DISABLED || 1592 pmctx->port->state == BR_STATE_BLOCKING) |
1531 goto out; 1532 1533 if (query->startup_sent < br->multicast_startup_query_count) 1534 query->startup_sent++; 1535 | 1593 goto out; 1594 1595 if (query->startup_sent < br->multicast_startup_query_count) 1596 query->startup_sent++; 1597 |
1536 br_multicast_send_query(port->br, port, query); | 1598 br_multicast_send_query(pmctx->port->br, pmctx->port, query); |
1537 1538out: 1539 spin_unlock(&br->multicast_lock); 1540} 1541 1542static void br_ip4_multicast_port_query_expired(struct timer_list *t) 1543{ | 1599 1600out: 1601 spin_unlock(&br->multicast_lock); 1602} 1603 1604static void br_ip4_multicast_port_query_expired(struct timer_list *t) 1605{ |
1544 struct net_bridge_port *port = from_timer(port, t, ip4_own_query.timer); | 1606 struct net_bridge_mcast_port *pmctx = from_timer(pmctx, t, 1607 ip4_own_query.timer); |
1545 | 1608 |
1546 br_multicast_port_query_expired(port, &port->ip4_own_query); | 1609 br_multicast_port_query_expired(pmctx, &pmctx->ip4_own_query); |
1547} 1548 1549#if IS_ENABLED(CONFIG_IPV6) 1550static void br_ip6_multicast_port_query_expired(struct timer_list *t) 1551{ | 1610} 1611 1612#if IS_ENABLED(CONFIG_IPV6) 1613static void br_ip6_multicast_port_query_expired(struct timer_list *t) 1614{ |
1552 struct net_bridge_port *port = from_timer(port, t, ip6_own_query.timer); | 1615 struct net_bridge_mcast_port *pmctx = from_timer(pmctx, t, 1616 ip6_own_query.timer); |
1553 | 1617 |
1554 br_multicast_port_query_expired(port, &port->ip6_own_query); | 1618 br_multicast_port_query_expired(pmctx, &pmctx->ip6_own_query); |
1555} 1556#endif 1557 1558static void br_multicast_port_group_rexmit(struct timer_list *t) 1559{ 1560 struct net_bridge_port_group *pg = from_timer(pg, t, rexmit_timer); 1561 struct bridge_mcast_other_query *other_query = NULL; 1562 struct net_bridge *br = pg->key.port->br; --- 38 unchanged lines hidden (view full) --- 1601 .id = SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED, 1602 .flags = SWITCHDEV_F_DEFER, 1603 .u.mc_disabled = !value, 1604 }; 1605 1606 return switchdev_port_attr_set(dev, &attr, extack); 1607} 1608 | 1619} 1620#endif 1621 1622static void br_multicast_port_group_rexmit(struct timer_list *t) 1623{ 1624 struct net_bridge_port_group *pg = from_timer(pg, t, rexmit_timer); 1625 struct bridge_mcast_other_query *other_query = NULL; 1626 struct net_bridge *br = pg->key.port->br; --- 38 unchanged lines hidden (view full) --- 1665 .id = SWITCHDEV_ATTR_ID_BRIDGE_MC_DISABLED, 1666 .flags = SWITCHDEV_F_DEFER, 1667 .u.mc_disabled = !value, 1668 }; 1669 1670 return switchdev_port_attr_set(dev, &attr, extack); 1671} 1672 |
1673static void br_multicast_port_ctx_init(struct net_bridge_port *port, 1674 struct net_bridge_mcast_port *pmctx) 1675{ 1676 pmctx->port = port; 1677 pmctx->multicast_router = MDB_RTR_TYPE_TEMP_QUERY; 1678 timer_setup(&pmctx->ip4_mc_router_timer, 1679 br_ip4_multicast_router_expired, 0); 1680 timer_setup(&pmctx->ip4_own_query.timer, 1681 br_ip4_multicast_port_query_expired, 0); 1682#if IS_ENABLED(CONFIG_IPV6) 1683 timer_setup(&pmctx->ip6_mc_router_timer, 1684 br_ip6_multicast_router_expired, 0); 1685 timer_setup(&pmctx->ip6_own_query.timer, 1686 br_ip6_multicast_port_query_expired, 0); 1687#endif 1688} 1689 1690static void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx) 1691{ 1692#if IS_ENABLED(CONFIG_IPV6) 1693 del_timer_sync(&pmctx->ip6_mc_router_timer); 1694#endif 1695 del_timer_sync(&pmctx->ip4_mc_router_timer); 1696} 1697 |
|
1609int br_multicast_add_port(struct net_bridge_port *port) 1610{ 1611 int err; 1612 | 1698int br_multicast_add_port(struct net_bridge_port *port) 1699{ 1700 int err; 1701 |
1613 port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY; | |
1614 port->multicast_eht_hosts_limit = BR_MCAST_DEFAULT_EHT_HOSTS_LIMIT; | 1702 port->multicast_eht_hosts_limit = BR_MCAST_DEFAULT_EHT_HOSTS_LIMIT; |
1703 br_multicast_port_ctx_init(port, &port->multicast_ctx); |
|
1615 | 1704 |
1616 timer_setup(&port->multicast_router_timer, 1617 br_multicast_router_expired, 0); 1618 timer_setup(&port->ip4_own_query.timer, 1619 br_ip4_multicast_port_query_expired, 0); 1620#if IS_ENABLED(CONFIG_IPV6) 1621 timer_setup(&port->ip6_own_query.timer, 1622 br_ip6_multicast_port_query_expired, 0); 1623#endif | |
1624 err = br_mc_disabled_update(port->dev, 1625 br_opt_get(port->br, 1626 BROPT_MULTICAST_ENABLED), 1627 NULL); 1628 if (err && err != -EOPNOTSUPP) 1629 return err; 1630 1631 port->mcast_stats = netdev_alloc_pcpu_stats(struct bridge_mcast_stats); --- 12 unchanged lines hidden (view full) --- 1644 1645 /* Take care of the remaining groups, only perm ones should be left */ 1646 spin_lock_bh(&br->multicast_lock); 1647 hlist_for_each_entry_safe(pg, n, &port->mglist, mglist) 1648 br_multicast_find_del_pg(br, pg); 1649 hlist_move_list(&br->mcast_gc_list, &deleted_head); 1650 spin_unlock_bh(&br->multicast_lock); 1651 br_multicast_gc(&deleted_head); | 1705 err = br_mc_disabled_update(port->dev, 1706 br_opt_get(port->br, 1707 BROPT_MULTICAST_ENABLED), 1708 NULL); 1709 if (err && err != -EOPNOTSUPP) 1710 return err; 1711 1712 port->mcast_stats = netdev_alloc_pcpu_stats(struct bridge_mcast_stats); --- 12 unchanged lines hidden (view full) --- 1725 1726 /* Take care of the remaining groups, only perm ones should be left */ 1727 spin_lock_bh(&br->multicast_lock); 1728 hlist_for_each_entry_safe(pg, n, &port->mglist, mglist) 1729 br_multicast_find_del_pg(br, pg); 1730 hlist_move_list(&br->mcast_gc_list, &deleted_head); 1731 spin_unlock_bh(&br->multicast_lock); 1732 br_multicast_gc(&deleted_head); |
1652 del_timer_sync(&port->multicast_router_timer); | 1733 br_multicast_port_ctx_deinit(&port->multicast_ctx); |
1653 free_percpu(port->mcast_stats); 1654} 1655 1656static void br_multicast_enable(struct bridge_mcast_own_query *query) 1657{ 1658 query->startup_sent = 0; 1659 1660 if (try_to_del_timer_sync(&query->timer) >= 0 || 1661 del_timer(&query->timer)) 1662 mod_timer(&query->timer, jiffies); 1663} 1664 1665static void __br_multicast_enable_port(struct net_bridge_port *port) 1666{ 1667 struct net_bridge *br = port->br; 1668 1669 if (!br_opt_get(br, BROPT_MULTICAST_ENABLED) || !netif_running(br->dev)) 1670 return; 1671 | 1734 free_percpu(port->mcast_stats); 1735} 1736 1737static void br_multicast_enable(struct bridge_mcast_own_query *query) 1738{ 1739 query->startup_sent = 0; 1740 1741 if (try_to_del_timer_sync(&query->timer) >= 0 || 1742 del_timer(&query->timer)) 1743 mod_timer(&query->timer, jiffies); 1744} 1745 1746static void __br_multicast_enable_port(struct net_bridge_port *port) 1747{ 1748 struct net_bridge *br = port->br; 1749 1750 if (!br_opt_get(br, BROPT_MULTICAST_ENABLED) || !netif_running(br->dev)) 1751 return; 1752 |
1672 br_multicast_enable(&port->ip4_own_query); | 1753 br_multicast_enable(&port->multicast_ctx.ip4_own_query); |
1673#if IS_ENABLED(CONFIG_IPV6) | 1754#if IS_ENABLED(CONFIG_IPV6) |
1674 br_multicast_enable(&port->ip6_own_query); | 1755 br_multicast_enable(&port->multicast_ctx.ip6_own_query); |
1675#endif | 1756#endif |
1676 if (port->multicast_router == MDB_RTR_TYPE_PERM && 1677 hlist_unhashed(&port->rlist)) 1678 br_multicast_add_router(br, port); | 1757 if (port->multicast_ctx.multicast_router == MDB_RTR_TYPE_PERM) { 1758 br_ip4_multicast_add_router(br, port); 1759 br_ip6_multicast_add_router(br, port); 1760 } |
1679} 1680 1681void br_multicast_enable_port(struct net_bridge_port *port) 1682{ 1683 struct net_bridge *br = port->br; 1684 1685 spin_lock(&br->multicast_lock); 1686 __br_multicast_enable_port(port); 1687 spin_unlock(&br->multicast_lock); 1688} 1689 1690void br_multicast_disable_port(struct net_bridge_port *port) 1691{ 1692 struct net_bridge *br = port->br; 1693 struct net_bridge_port_group *pg; 1694 struct hlist_node *n; | 1761} 1762 1763void br_multicast_enable_port(struct net_bridge_port *port) 1764{ 1765 struct net_bridge *br = port->br; 1766 1767 spin_lock(&br->multicast_lock); 1768 __br_multicast_enable_port(port); 1769 spin_unlock(&br->multicast_lock); 1770} 1771 1772void br_multicast_disable_port(struct net_bridge_port *port) 1773{ 1774 struct net_bridge *br = port->br; 1775 struct net_bridge_port_group *pg; 1776 struct hlist_node *n; |
1777 bool del = false; |
|
1695 1696 spin_lock(&br->multicast_lock); 1697 hlist_for_each_entry_safe(pg, n, &port->mglist, mglist) 1698 if (!(pg->flags & MDB_PG_FLAGS_PERMANENT)) 1699 br_multicast_find_del_pg(br, pg); 1700 | 1778 1779 spin_lock(&br->multicast_lock); 1780 hlist_for_each_entry_safe(pg, n, &port->mglist, mglist) 1781 if (!(pg->flags & MDB_PG_FLAGS_PERMANENT)) 1782 br_multicast_find_del_pg(br, pg); 1783 |
1701 __del_port_router(port); 1702 1703 del_timer(&port->multicast_router_timer); 1704 del_timer(&port->ip4_own_query.timer); | 1784 del |= br_ip4_multicast_rport_del(port); 1785 del_timer(&port->multicast_ctx.ip4_mc_router_timer); 1786 del_timer(&port->multicast_ctx.ip4_own_query.timer); 1787 del |= br_ip6_multicast_rport_del(port); |
1705#if IS_ENABLED(CONFIG_IPV6) | 1788#if IS_ENABLED(CONFIG_IPV6) |
1706 del_timer(&port->ip6_own_query.timer); | 1789 del_timer(&port->multicast_ctx.ip6_mc_router_timer); 1790 del_timer(&port->multicast_ctx.ip6_own_query.timer); |
1707#endif | 1791#endif |
1792 br_multicast_rport_del_notify(port, del); |
|
1708 spin_unlock(&br->multicast_lock); 1709} 1710 1711static int __grp_src_delete_marked(struct net_bridge_port_group *pg) 1712{ 1713 struct net_bridge_group_src *ent; 1714 struct hlist_node *tmp; 1715 int deleted = 0; --- 894 unchanged lines hidden (view full) --- 2610 2611 /* update protected by general multicast_lock by caller */ 2612 rcu_assign_pointer(br->ip6_querier.port, port); 2613 2614 return true; 2615} 2616#endif 2617 | 1793 spin_unlock(&br->multicast_lock); 1794} 1795 1796static int __grp_src_delete_marked(struct net_bridge_port_group *pg) 1797{ 1798 struct net_bridge_group_src *ent; 1799 struct hlist_node *tmp; 1800 int deleted = 0; --- 894 unchanged lines hidden (view full) --- 2695 2696 /* update protected by general multicast_lock by caller */ 2697 rcu_assign_pointer(br->ip6_querier.port, port); 2698 2699 return true; 2700} 2701#endif 2702 |
2618static bool br_multicast_select_querier(struct net_bridge *br, 2619 struct net_bridge_port *port, 2620 struct br_ip *saddr) 2621{ 2622 switch (saddr->proto) { 2623 case htons(ETH_P_IP): 2624 return br_ip4_multicast_select_querier(br, port, saddr->src.ip4); 2625#if IS_ENABLED(CONFIG_IPV6) 2626 case htons(ETH_P_IPV6): 2627 return br_ip6_multicast_select_querier(br, port, &saddr->src.ip6); 2628#endif 2629 } 2630 2631 return false; 2632} 2633 | |
2634static void 2635br_multicast_update_query_timer(struct net_bridge *br, 2636 struct bridge_mcast_other_query *query, 2637 unsigned long max_delay) 2638{ 2639 if (!timer_pending(&query->timer)) 2640 query->delay_time = jiffies + max_delay; 2641 --- 8 unchanged lines hidden (view full) --- 2650 .id = SWITCHDEV_ATTR_ID_PORT_MROUTER, 2651 .flags = SWITCHDEV_F_DEFER, 2652 .u.mrouter = is_mc_router, 2653 }; 2654 2655 switchdev_port_attr_set(p->dev, &attr, NULL); 2656} 2657 | 2703static void 2704br_multicast_update_query_timer(struct net_bridge *br, 2705 struct bridge_mcast_other_query *query, 2706 unsigned long max_delay) 2707{ 2708 if (!timer_pending(&query->timer)) 2709 query->delay_time = jiffies + max_delay; 2710 --- 8 unchanged lines hidden (view full) --- 2719 .id = SWITCHDEV_ATTR_ID_PORT_MROUTER, 2720 .flags = SWITCHDEV_F_DEFER, 2721 .u.mrouter = is_mc_router, 2722 }; 2723 2724 switchdev_port_attr_set(p->dev, &attr, NULL); 2725} 2726 |
2658/* 2659 * Add port to router_list | 2727static struct net_bridge_port * 2728br_multicast_rport_from_node(struct net_bridge *br, 2729 struct hlist_head *mc_router_list, 2730 struct hlist_node *rlist) 2731{ 2732 struct net_bridge_mcast_port *pmctx; 2733 2734#if IS_ENABLED(CONFIG_IPV6) 2735 if (mc_router_list == &br->ip6_mc_router_list) 2736 pmctx = hlist_entry(rlist, struct net_bridge_mcast_port, 2737 ip6_rlist); 2738 else 2739#endif 2740 pmctx = hlist_entry(rlist, struct net_bridge_mcast_port, 2741 ip4_rlist); 2742 2743 return pmctx->port; 2744} 2745 2746static struct hlist_node * 2747br_multicast_get_rport_slot(struct net_bridge *br, 2748 struct net_bridge_port *port, 2749 struct hlist_head *mc_router_list) 2750 2751{ 2752 struct hlist_node *slot = NULL; 2753 struct net_bridge_port *p; 2754 struct hlist_node *rlist; 2755 2756 hlist_for_each(rlist, mc_router_list) { 2757 p = br_multicast_rport_from_node(br, mc_router_list, rlist); 2758 2759 if ((unsigned long)port >= (unsigned long)p) 2760 break; 2761 2762 slot = rlist; 2763 } 2764 2765 return slot; 2766} 2767 2768static bool br_multicast_no_router_otherpf(struct net_bridge_port *port, 2769 struct hlist_node *rnode) 2770{ 2771#if IS_ENABLED(CONFIG_IPV6) 2772 if (rnode != &port->multicast_ctx.ip6_rlist) 2773 return hlist_unhashed(&port->multicast_ctx.ip6_rlist); 2774 else 2775 return hlist_unhashed(&port->multicast_ctx.ip4_rlist); 2776#else 2777 return true; 2778#endif 2779} 2780 2781/* Add port to router_list |
2660 * list is maintained ordered by pointer value 2661 * and locked by br->multicast_lock and RCU 2662 */ 2663static void br_multicast_add_router(struct net_bridge *br, | 2782 * list is maintained ordered by pointer value 2783 * and locked by br->multicast_lock and RCU 2784 */ 2785static void br_multicast_add_router(struct net_bridge *br, |
2664 struct net_bridge_port *port) | 2786 struct net_bridge_port *port, 2787 struct hlist_node *rlist, 2788 struct hlist_head *mc_router_list) |
2665{ | 2789{ |
2666 struct net_bridge_port *p; 2667 struct hlist_node *slot = NULL; | 2790 struct hlist_node *slot; |
2668 | 2791 |
2669 if (!hlist_unhashed(&port->rlist)) | 2792 if (!hlist_unhashed(rlist)) |
2670 return; 2671 | 2793 return; 2794 |
2672 hlist_for_each_entry(p, &br->router_list, rlist) { 2673 if ((unsigned long) port >= (unsigned long) p) 2674 break; 2675 slot = &p->rlist; 2676 } | 2795 slot = br_multicast_get_rport_slot(br, port, mc_router_list); |
2677 2678 if (slot) | 2796 2797 if (slot) |
2679 hlist_add_behind_rcu(&port->rlist, slot); | 2798 hlist_add_behind_rcu(rlist, slot); |
2680 else | 2799 else |
2681 hlist_add_head_rcu(&port->rlist, &br->router_list); 2682 br_rtr_notify(br->dev, port, RTM_NEWMDB); 2683 br_port_mc_router_state_change(port, true); | 2800 hlist_add_head_rcu(rlist, mc_router_list); 2801 2802 /* For backwards compatibility for now, only notify if we 2803 * switched from no IPv4/IPv6 multicast router to a new 2804 * IPv4 or IPv6 multicast router. 2805 */ 2806 if (br_multicast_no_router_otherpf(port, rlist)) { 2807 br_rtr_notify(br->dev, port, RTM_NEWMDB); 2808 br_port_mc_router_state_change(port, true); 2809 } |
2684} 2685 | 2810} 2811 |
2812/* Add port to router_list 2813 * list is maintained ordered by pointer value 2814 * and locked by br->multicast_lock and RCU 2815 */ 2816static void br_ip4_multicast_add_router(struct net_bridge *br, 2817 struct net_bridge_port *port) 2818{ 2819 br_multicast_add_router(br, port, &port->multicast_ctx.ip4_rlist, 2820 &br->ip4_mc_router_list); 2821} 2822 2823/* Add port to router_list 2824 * list is maintained ordered by pointer value 2825 * and locked by br->multicast_lock and RCU 2826 */ 2827static void br_ip6_multicast_add_router(struct net_bridge *br, 2828 struct net_bridge_port *port) 2829{ 2830#if IS_ENABLED(CONFIG_IPV6) 2831 br_multicast_add_router(br, port, &port->multicast_ctx.ip6_rlist, 2832 &br->ip6_mc_router_list); 2833#endif 2834} 2835 |
|
2686static void br_multicast_mark_router(struct net_bridge *br, | 2836static void br_multicast_mark_router(struct net_bridge *br, |
2687 struct net_bridge_port *port) | 2837 struct net_bridge_port *port, 2838 struct timer_list *timer, 2839 struct hlist_node *rlist, 2840 struct hlist_head *mc_router_list) |
2688{ 2689 unsigned long now = jiffies; 2690 2691 if (!port) { 2692 if (br->multicast_router == MDB_RTR_TYPE_TEMP_QUERY) { | 2841{ 2842 unsigned long now = jiffies; 2843 2844 if (!port) { 2845 if (br->multicast_router == MDB_RTR_TYPE_TEMP_QUERY) { |
2693 if (!timer_pending(&br->multicast_router_timer)) | 2846 if (!br_ip4_multicast_is_router(br) && 2847 !br_ip6_multicast_is_router(br)) |
2694 br_mc_router_state_change(br, true); | 2848 br_mc_router_state_change(br, true); |
2695 mod_timer(&br->multicast_router_timer, 2696 now + br->multicast_querier_interval); | 2849 mod_timer(timer, now + br->multicast_querier_interval); |
2697 } 2698 return; 2699 } 2700 | 2850 } 2851 return; 2852 } 2853 |
2701 if (port->multicast_router == MDB_RTR_TYPE_DISABLED || 2702 port->multicast_router == MDB_RTR_TYPE_PERM) | 2854 if (port->multicast_ctx.multicast_router == MDB_RTR_TYPE_DISABLED || 2855 port->multicast_ctx.multicast_router == MDB_RTR_TYPE_PERM) |
2703 return; 2704 | 2856 return; 2857 |
2705 br_multicast_add_router(br, port); | 2858 br_multicast_add_router(br, port, rlist, mc_router_list); 2859 mod_timer(timer, now + br->multicast_querier_interval); 2860} |
2706 | 2861 |
2707 mod_timer(&port->multicast_router_timer, 2708 now + br->multicast_querier_interval); | 2862static void br_ip4_multicast_mark_router(struct net_bridge *br, 2863 struct net_bridge_port *port) 2864{ 2865 struct timer_list *timer = &br->ip4_mc_router_timer; 2866 struct hlist_node *rlist = NULL; 2867 2868 if (port) { 2869 timer = &port->multicast_ctx.ip4_mc_router_timer; 2870 rlist = &port->multicast_ctx.ip4_rlist; 2871 } 2872 2873 br_multicast_mark_router(br, port, timer, rlist, 2874 &br->ip4_mc_router_list); |
2709} 2710 | 2875} 2876 |
2711static void br_multicast_query_received(struct net_bridge *br, 2712 struct net_bridge_port *port, 2713 struct bridge_mcast_other_query *query, 2714 struct br_ip *saddr, 2715 unsigned long max_delay) | 2877static void br_ip6_multicast_mark_router(struct net_bridge *br, 2878 struct net_bridge_port *port) |
2716{ | 2879{ |
2717 if (!br_multicast_select_querier(br, port, saddr)) | 2880#if IS_ENABLED(CONFIG_IPV6) 2881 struct timer_list *timer = &br->ip6_mc_router_timer; 2882 struct hlist_node *rlist = NULL; 2883 2884 if (port) { 2885 timer = &port->multicast_ctx.ip6_mc_router_timer; 2886 rlist = &port->multicast_ctx.ip6_rlist; 2887 } 2888 2889 br_multicast_mark_router(br, port, timer, rlist, 2890 &br->ip6_mc_router_list); 2891#endif 2892} 2893 2894static void 2895br_ip4_multicast_query_received(struct net_bridge *br, 2896 struct net_bridge_port *port, 2897 struct bridge_mcast_other_query *query, 2898 struct br_ip *saddr, 2899 unsigned long max_delay) 2900{ 2901 if (!br_ip4_multicast_select_querier(br, port, saddr->src.ip4)) |
2718 return; 2719 2720 br_multicast_update_query_timer(br, query, max_delay); | 2902 return; 2903 2904 br_multicast_update_query_timer(br, query, max_delay); |
2721 br_multicast_mark_router(br, port); | 2905 br_ip4_multicast_mark_router(br, port); |
2722} 2723 | 2906} 2907 |
2908#if IS_ENABLED(CONFIG_IPV6) 2909static void 2910br_ip6_multicast_query_received(struct net_bridge *br, 2911 struct net_bridge_port *port, 2912 struct bridge_mcast_other_query *query, 2913 struct br_ip *saddr, 2914 unsigned long max_delay) 2915{ 2916 if (!br_ip6_multicast_select_querier(br, port, &saddr->src.ip6)) 2917 return; 2918 2919 br_multicast_update_query_timer(br, query, max_delay); 2920 br_ip6_multicast_mark_router(br, port); 2921} 2922#endif 2923 |
|
2724static void br_ip4_multicast_query(struct net_bridge *br, 2725 struct net_bridge_port *port, 2726 struct sk_buff *skb, 2727 u16 vid) 2728{ 2729 unsigned int transport_len = ip_transport_len(skb); 2730 const struct iphdr *iph = ip_hdr(skb); 2731 struct igmphdr *ih = igmp_hdr(skb); --- 31 unchanged lines hidden (view full) --- 2763 } else { 2764 goto out; 2765 } 2766 2767 if (!group) { 2768 saddr.proto = htons(ETH_P_IP); 2769 saddr.src.ip4 = iph->saddr; 2770 | 2924static void br_ip4_multicast_query(struct net_bridge *br, 2925 struct net_bridge_port *port, 2926 struct sk_buff *skb, 2927 u16 vid) 2928{ 2929 unsigned int transport_len = ip_transport_len(skb); 2930 const struct iphdr *iph = ip_hdr(skb); 2931 struct igmphdr *ih = igmp_hdr(skb); --- 31 unchanged lines hidden (view full) --- 2963 } else { 2964 goto out; 2965 } 2966 2967 if (!group) { 2968 saddr.proto = htons(ETH_P_IP); 2969 saddr.src.ip4 = iph->saddr; 2970 |
2771 br_multicast_query_received(br, port, &br->ip4_other_query, 2772 &saddr, max_delay); | 2971 br_ip4_multicast_query_received(br, port, &br->ip4_other_query, 2972 &saddr, max_delay); |
2773 goto out; 2774 } 2775 2776 mp = br_mdb_ip4_get(br, group, vid); 2777 if (!mp) 2778 goto out; 2779 2780 max_delay *= br->multicast_last_member_count; --- 70 unchanged lines hidden (view full) --- 2851 } 2852 2853 is_general_query = group && ipv6_addr_any(group); 2854 2855 if (is_general_query) { 2856 saddr.proto = htons(ETH_P_IPV6); 2857 saddr.src.ip6 = ipv6_hdr(skb)->saddr; 2858 | 2973 goto out; 2974 } 2975 2976 mp = br_mdb_ip4_get(br, group, vid); 2977 if (!mp) 2978 goto out; 2979 2980 max_delay *= br->multicast_last_member_count; --- 70 unchanged lines hidden (view full) --- 3051 } 3052 3053 is_general_query = group && ipv6_addr_any(group); 3054 3055 if (is_general_query) { 3056 saddr.proto = htons(ETH_P_IPV6); 3057 saddr.src.ip6 = ipv6_hdr(skb)->saddr; 3058 |
2859 br_multicast_query_received(br, port, &br->ip6_other_query, 2860 &saddr, max_delay); | 3059 br_ip6_multicast_query_received(br, port, &br->ip6_other_query, 3060 &saddr, max_delay); |
2861 goto out; 2862 } else if (!group) { 2863 goto out; 2864 } 2865 2866 mp = br_mdb_ip6_get(br, group, vid); 2867 if (!mp) 2868 goto out; --- 132 unchanged lines hidden (view full) --- 3001 const unsigned char *src) 3002{ 3003 struct br_ip br_group; 3004 struct bridge_mcast_own_query *own_query; 3005 3006 if (ipv4_is_local_multicast(group)) 3007 return; 3008 | 3061 goto out; 3062 } else if (!group) { 3063 goto out; 3064 } 3065 3066 mp = br_mdb_ip6_get(br, group, vid); 3067 if (!mp) 3068 goto out; --- 132 unchanged lines hidden (view full) --- 3201 const unsigned char *src) 3202{ 3203 struct br_ip br_group; 3204 struct bridge_mcast_own_query *own_query; 3205 3206 if (ipv4_is_local_multicast(group)) 3207 return; 3208 |
3009 own_query = port ? &port->ip4_own_query : &br->ip4_own_query; | 3209 own_query = port ? &port->multicast_ctx.ip4_own_query : 3210 &br->ip4_own_query; |
3010 3011 memset(&br_group, 0, sizeof(br_group)); 3012 br_group.dst.ip4 = group; 3013 br_group.proto = htons(ETH_P_IP); 3014 br_group.vid = vid; 3015 3016 br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query, 3017 own_query, src); --- 7 unchanged lines hidden (view full) --- 3025 const unsigned char *src) 3026{ 3027 struct br_ip br_group; 3028 struct bridge_mcast_own_query *own_query; 3029 3030 if (ipv6_addr_is_ll_all_nodes(group)) 3031 return; 3032 | 3211 3212 memset(&br_group, 0, sizeof(br_group)); 3213 br_group.dst.ip4 = group; 3214 br_group.proto = htons(ETH_P_IP); 3215 br_group.vid = vid; 3216 3217 br_multicast_leave_group(br, port, &br_group, &br->ip4_other_query, 3218 own_query, src); --- 7 unchanged lines hidden (view full) --- 3226 const unsigned char *src) 3227{ 3228 struct br_ip br_group; 3229 struct bridge_mcast_own_query *own_query; 3230 3231 if (ipv6_addr_is_ll_all_nodes(group)) 3232 return; 3233 |
3033 own_query = port ? &port->ip6_own_query : &br->ip6_own_query; | 3234 own_query = port ? &port->multicast_ctx.ip6_own_query : 3235 &br->ip6_own_query; |
3034 3035 memset(&br_group, 0, sizeof(br_group)); 3036 br_group.dst.ip6 = *group; 3037 br_group.proto = htons(ETH_P_IPV6); 3038 br_group.vid = vid; 3039 3040 br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query, 3041 own_query, src); --- 40 unchanged lines hidden (view full) --- 3082 unsigned int offset = skb_transport_offset(skb); 3083 struct pimhdr *pimhdr, _pimhdr; 3084 3085 pimhdr = skb_header_pointer(skb, offset, sizeof(_pimhdr), &_pimhdr); 3086 if (!pimhdr || pim_hdr_version(pimhdr) != PIM_VERSION || 3087 pim_hdr_type(pimhdr) != PIM_TYPE_HELLO) 3088 return; 3089 | 3236 3237 memset(&br_group, 0, sizeof(br_group)); 3238 br_group.dst.ip6 = *group; 3239 br_group.proto = htons(ETH_P_IPV6); 3240 br_group.vid = vid; 3241 3242 br_multicast_leave_group(br, port, &br_group, &br->ip6_other_query, 3243 own_query, src); --- 40 unchanged lines hidden (view full) --- 3284 unsigned int offset = skb_transport_offset(skb); 3285 struct pimhdr *pimhdr, _pimhdr; 3286 3287 pimhdr = skb_header_pointer(skb, offset, sizeof(_pimhdr), &_pimhdr); 3288 if (!pimhdr || pim_hdr_version(pimhdr) != PIM_VERSION || 3289 pim_hdr_type(pimhdr) != PIM_TYPE_HELLO) 3290 return; 3291 |
3090 br_multicast_mark_router(br, port); | 3292 spin_lock(&br->multicast_lock); 3293 br_ip4_multicast_mark_router(br, port); 3294 spin_unlock(&br->multicast_lock); |
3091} 3092 3093static int br_ip4_multicast_mrd_rcv(struct net_bridge *br, 3094 struct net_bridge_port *port, 3095 struct sk_buff *skb) 3096{ 3097 if (ip_hdr(skb)->protocol != IPPROTO_IGMP || 3098 igmp_hdr(skb)->type != IGMP_MRDISC_ADV) 3099 return -ENOMSG; 3100 | 3295} 3296 3297static int br_ip4_multicast_mrd_rcv(struct net_bridge *br, 3298 struct net_bridge_port *port, 3299 struct sk_buff *skb) 3300{ 3301 if (ip_hdr(skb)->protocol != IPPROTO_IGMP || 3302 igmp_hdr(skb)->type != IGMP_MRDISC_ADV) 3303 return -ENOMSG; 3304 |
3101 br_multicast_mark_router(br, port); | 3305 spin_lock(&br->multicast_lock); 3306 br_ip4_multicast_mark_router(br, port); 3307 spin_unlock(&br->multicast_lock); |
3102 3103 return 0; 3104} 3105 3106static int br_multicast_ipv4_rcv(struct net_bridge *br, 3107 struct net_bridge_port *port, 3108 struct sk_buff *skb, 3109 u16 vid) --- 51 unchanged lines hidden (view full) --- 3161#if IS_ENABLED(CONFIG_IPV6) 3162static void br_ip6_multicast_mrd_rcv(struct net_bridge *br, 3163 struct net_bridge_port *port, 3164 struct sk_buff *skb) 3165{ 3166 if (icmp6_hdr(skb)->icmp6_type != ICMPV6_MRDISC_ADV) 3167 return; 3168 | 3308 3309 return 0; 3310} 3311 3312static int br_multicast_ipv4_rcv(struct net_bridge *br, 3313 struct net_bridge_port *port, 3314 struct sk_buff *skb, 3315 u16 vid) --- 51 unchanged lines hidden (view full) --- 3367#if IS_ENABLED(CONFIG_IPV6) 3368static void br_ip6_multicast_mrd_rcv(struct net_bridge *br, 3369 struct net_bridge_port *port, 3370 struct sk_buff *skb) 3371{ 3372 if (icmp6_hdr(skb)->icmp6_type != ICMPV6_MRDISC_ADV) 3373 return; 3374 |
3169 br_multicast_mark_router(br, port); | 3375 spin_lock(&br->multicast_lock); 3376 br_ip6_multicast_mark_router(br, port); 3377 spin_unlock(&br->multicast_lock); |
3170} 3171 3172static int br_multicast_ipv6_rcv(struct net_bridge *br, 3173 struct net_bridge_port *port, 3174 struct sk_buff *skb, 3175 u16 vid) 3176{ 3177 const unsigned char *src; --- 133 unchanged lines hidden (view full) --- 3311 br->multicast_mld_version = 1; 3312 br->ip6_other_query.delay_time = 0; 3313 br->ip6_querier.port = NULL; 3314#endif 3315 br_opt_toggle(br, BROPT_MULTICAST_ENABLED, true); 3316 br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, true); 3317 3318 spin_lock_init(&br->multicast_lock); | 3378} 3379 3380static int br_multicast_ipv6_rcv(struct net_bridge *br, 3381 struct net_bridge_port *port, 3382 struct sk_buff *skb, 3383 u16 vid) 3384{ 3385 const unsigned char *src; --- 133 unchanged lines hidden (view full) --- 3519 br->multicast_mld_version = 1; 3520 br->ip6_other_query.delay_time = 0; 3521 br->ip6_querier.port = NULL; 3522#endif 3523 br_opt_toggle(br, BROPT_MULTICAST_ENABLED, true); 3524 br_opt_toggle(br, BROPT_HAS_IPV6_ADDR, true); 3525 3526 spin_lock_init(&br->multicast_lock); |
3319 timer_setup(&br->multicast_router_timer, 3320 br_multicast_local_router_expired, 0); | 3527 timer_setup(&br->ip4_mc_router_timer, 3528 br_ip4_multicast_local_router_expired, 0); |
3321 timer_setup(&br->ip4_other_query.timer, 3322 br_ip4_multicast_querier_expired, 0); 3323 timer_setup(&br->ip4_own_query.timer, 3324 br_ip4_multicast_query_expired, 0); 3325#if IS_ENABLED(CONFIG_IPV6) | 3529 timer_setup(&br->ip4_other_query.timer, 3530 br_ip4_multicast_querier_expired, 0); 3531 timer_setup(&br->ip4_own_query.timer, 3532 br_ip4_multicast_query_expired, 0); 3533#if IS_ENABLED(CONFIG_IPV6) |
3534 timer_setup(&br->ip6_mc_router_timer, 3535 br_ip6_multicast_local_router_expired, 0); |
|
3326 timer_setup(&br->ip6_other_query.timer, 3327 br_ip6_multicast_querier_expired, 0); 3328 timer_setup(&br->ip6_own_query.timer, 3329 br_ip6_multicast_query_expired, 0); 3330#endif 3331 INIT_HLIST_HEAD(&br->mdb_list); 3332 INIT_HLIST_HEAD(&br->mcast_gc_list); 3333 INIT_WORK(&br->mcast_gc_work, br_multicast_gc_work); --- 77 unchanged lines hidden (view full) --- 3411 __br_multicast_open(br, &br->ip4_own_query); 3412#if IS_ENABLED(CONFIG_IPV6) 3413 __br_multicast_open(br, &br->ip6_own_query); 3414#endif 3415} 3416 3417void br_multicast_stop(struct net_bridge *br) 3418{ | 3536 timer_setup(&br->ip6_other_query.timer, 3537 br_ip6_multicast_querier_expired, 0); 3538 timer_setup(&br->ip6_own_query.timer, 3539 br_ip6_multicast_query_expired, 0); 3540#endif 3541 INIT_HLIST_HEAD(&br->mdb_list); 3542 INIT_HLIST_HEAD(&br->mcast_gc_list); 3543 INIT_WORK(&br->mcast_gc_work, br_multicast_gc_work); --- 77 unchanged lines hidden (view full) --- 3621 __br_multicast_open(br, &br->ip4_own_query); 3622#if IS_ENABLED(CONFIG_IPV6) 3623 __br_multicast_open(br, &br->ip6_own_query); 3624#endif 3625} 3626 3627void br_multicast_stop(struct net_bridge *br) 3628{ |
3419 del_timer_sync(&br->multicast_router_timer); | 3629 del_timer_sync(&br->ip4_mc_router_timer); |
3420 del_timer_sync(&br->ip4_other_query.timer); 3421 del_timer_sync(&br->ip4_own_query.timer); 3422#if IS_ENABLED(CONFIG_IPV6) | 3630 del_timer_sync(&br->ip4_other_query.timer); 3631 del_timer_sync(&br->ip4_own_query.timer); 3632#if IS_ENABLED(CONFIG_IPV6) |
3633 del_timer_sync(&br->ip6_mc_router_timer); |
|
3423 del_timer_sync(&br->ip6_other_query.timer); 3424 del_timer_sync(&br->ip6_own_query.timer); 3425#endif 3426} 3427 3428void br_multicast_dev_del(struct net_bridge *br) 3429{ 3430 struct net_bridge_mdb_entry *mp; --- 17 unchanged lines hidden (view full) --- 3448 int err = -EINVAL; 3449 3450 spin_lock_bh(&br->multicast_lock); 3451 3452 switch (val) { 3453 case MDB_RTR_TYPE_DISABLED: 3454 case MDB_RTR_TYPE_PERM: 3455 br_mc_router_state_change(br, val == MDB_RTR_TYPE_PERM); | 3634 del_timer_sync(&br->ip6_other_query.timer); 3635 del_timer_sync(&br->ip6_own_query.timer); 3636#endif 3637} 3638 3639void br_multicast_dev_del(struct net_bridge *br) 3640{ 3641 struct net_bridge_mdb_entry *mp; --- 17 unchanged lines hidden (view full) --- 3659 int err = -EINVAL; 3660 3661 spin_lock_bh(&br->multicast_lock); 3662 3663 switch (val) { 3664 case MDB_RTR_TYPE_DISABLED: 3665 case MDB_RTR_TYPE_PERM: 3666 br_mc_router_state_change(br, val == MDB_RTR_TYPE_PERM); |
3456 del_timer(&br->multicast_router_timer); | 3667 del_timer(&br->ip4_mc_router_timer); 3668#if IS_ENABLED(CONFIG_IPV6) 3669 del_timer(&br->ip6_mc_router_timer); 3670#endif |
3457 br->multicast_router = val; 3458 err = 0; 3459 break; 3460 case MDB_RTR_TYPE_TEMP_QUERY: 3461 if (br->multicast_router != MDB_RTR_TYPE_TEMP_QUERY) 3462 br_mc_router_state_change(br, false); 3463 br->multicast_router = val; 3464 err = 0; 3465 break; 3466 } 3467 3468 spin_unlock_bh(&br->multicast_lock); 3469 3470 return err; 3471} 3472 | 3671 br->multicast_router = val; 3672 err = 0; 3673 break; 3674 case MDB_RTR_TYPE_TEMP_QUERY: 3675 if (br->multicast_router != MDB_RTR_TYPE_TEMP_QUERY) 3676 br_mc_router_state_change(br, false); 3677 br->multicast_router = val; 3678 err = 0; 3679 break; 3680 } 3681 3682 spin_unlock_bh(&br->multicast_lock); 3683 3684 return err; 3685} 3686 |
3473static void __del_port_router(struct net_bridge_port *p) | 3687static void 3688br_multicast_rport_del_notify(struct net_bridge_port *p, bool deleted) |
3474{ | 3689{ |
3475 if (hlist_unhashed(&p->rlist)) | 3690 if (!deleted) |
3476 return; | 3691 return; |
3477 hlist_del_init_rcu(&p->rlist); | 3692 3693 /* For backwards compatibility for now, only notify if there is 3694 * no multicast router anymore for both IPv4 and IPv6. 3695 */ 3696 if (!hlist_unhashed(&p->multicast_ctx.ip4_rlist)) 3697 return; 3698#if IS_ENABLED(CONFIG_IPV6) 3699 if (!hlist_unhashed(&p->multicast_ctx.ip6_rlist)) 3700 return; 3701#endif 3702 |
3478 br_rtr_notify(p->br->dev, p, RTM_DELMDB); 3479 br_port_mc_router_state_change(p, false); 3480 3481 /* don't allow timer refresh */ | 3703 br_rtr_notify(p->br->dev, p, RTM_DELMDB); 3704 br_port_mc_router_state_change(p, false); 3705 3706 /* don't allow timer refresh */ |
3482 if (p->multicast_router == MDB_RTR_TYPE_TEMP) 3483 p->multicast_router = MDB_RTR_TYPE_TEMP_QUERY; | 3707 if (p->multicast_ctx.multicast_router == MDB_RTR_TYPE_TEMP) 3708 p->multicast_ctx.multicast_router = MDB_RTR_TYPE_TEMP_QUERY; |
3484} 3485 3486int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) 3487{ 3488 struct net_bridge *br = p->br; 3489 unsigned long now = jiffies; 3490 int err = -EINVAL; | 3709} 3710 3711int br_multicast_set_port_router(struct net_bridge_port *p, unsigned long val) 3712{ 3713 struct net_bridge *br = p->br; 3714 unsigned long now = jiffies; 3715 int err = -EINVAL; |
3716 bool del = false; |
|
3491 3492 spin_lock(&br->multicast_lock); | 3717 3718 spin_lock(&br->multicast_lock); |
3493 if (p->multicast_router == val) { | 3719 if (p->multicast_ctx.multicast_router == val) { |
3494 /* Refresh the temp router port timer */ | 3720 /* Refresh the temp router port timer */ |
3495 if (p->multicast_router == MDB_RTR_TYPE_TEMP) 3496 mod_timer(&p->multicast_router_timer, | 3721 if (p->multicast_ctx.multicast_router == MDB_RTR_TYPE_TEMP) { 3722 mod_timer(&p->multicast_ctx.ip4_mc_router_timer, |
3497 now + br->multicast_querier_interval); | 3723 now + br->multicast_querier_interval); |
3724#if IS_ENABLED(CONFIG_IPV6) 3725 mod_timer(&p->multicast_ctx.ip6_mc_router_timer, 3726 now + br->multicast_querier_interval); 3727#endif 3728 } |
|
3498 err = 0; 3499 goto unlock; 3500 } 3501 switch (val) { 3502 case MDB_RTR_TYPE_DISABLED: | 3729 err = 0; 3730 goto unlock; 3731 } 3732 switch (val) { 3733 case MDB_RTR_TYPE_DISABLED: |
3503 p->multicast_router = MDB_RTR_TYPE_DISABLED; 3504 __del_port_router(p); 3505 del_timer(&p->multicast_router_timer); | 3734 p->multicast_ctx.multicast_router = MDB_RTR_TYPE_DISABLED; 3735 del |= br_ip4_multicast_rport_del(p); 3736 del_timer(&p->multicast_ctx.ip4_mc_router_timer); 3737 del |= br_ip6_multicast_rport_del(p); 3738#if IS_ENABLED(CONFIG_IPV6) 3739 del_timer(&p->multicast_ctx.ip6_mc_router_timer); 3740#endif 3741 br_multicast_rport_del_notify(p, del); |
3506 break; 3507 case MDB_RTR_TYPE_TEMP_QUERY: | 3742 break; 3743 case MDB_RTR_TYPE_TEMP_QUERY: |
3508 p->multicast_router = MDB_RTR_TYPE_TEMP_QUERY; 3509 __del_port_router(p); | 3744 p->multicast_ctx.multicast_router = MDB_RTR_TYPE_TEMP_QUERY; 3745 del |= br_ip4_multicast_rport_del(p); 3746 del |= br_ip6_multicast_rport_del(p); 3747 br_multicast_rport_del_notify(p, del); |
3510 break; 3511 case MDB_RTR_TYPE_PERM: | 3748 break; 3749 case MDB_RTR_TYPE_PERM: |
3512 p->multicast_router = MDB_RTR_TYPE_PERM; 3513 del_timer(&p->multicast_router_timer); 3514 br_multicast_add_router(br, p); | 3750 p->multicast_ctx.multicast_router = MDB_RTR_TYPE_PERM; 3751 del_timer(&p->multicast_ctx.ip4_mc_router_timer); 3752 br_ip4_multicast_add_router(br, p); 3753#if IS_ENABLED(CONFIG_IPV6) 3754 del_timer(&p->multicast_ctx.ip6_mc_router_timer); 3755#endif 3756 br_ip6_multicast_add_router(br, p); |
3515 break; 3516 case MDB_RTR_TYPE_TEMP: | 3757 break; 3758 case MDB_RTR_TYPE_TEMP: |
3517 p->multicast_router = MDB_RTR_TYPE_TEMP; 3518 br_multicast_mark_router(br, p); | 3759 p->multicast_ctx.multicast_router = MDB_RTR_TYPE_TEMP; 3760 br_ip4_multicast_mark_router(br, p); 3761 br_ip6_multicast_mark_router(br, p); |
3519 break; 3520 default: 3521 goto unlock; 3522 } 3523 err = 0; 3524unlock: 3525 spin_unlock(&br->multicast_lock); 3526 --- 9 unchanged lines hidden (view full) --- 3536 3537 rcu_read_lock(); 3538 list_for_each_entry_rcu(port, &br->port_list, list) { 3539 if (port->state == BR_STATE_DISABLED || 3540 port->state == BR_STATE_BLOCKING) 3541 continue; 3542 3543 if (query == &br->ip4_own_query) | 3762 break; 3763 default: 3764 goto unlock; 3765 } 3766 err = 0; 3767unlock: 3768 spin_unlock(&br->multicast_lock); 3769 --- 9 unchanged lines hidden (view full) --- 3779 3780 rcu_read_lock(); 3781 list_for_each_entry_rcu(port, &br->port_list, list) { 3782 if (port->state == BR_STATE_DISABLED || 3783 port->state == BR_STATE_BLOCKING) 3784 continue; 3785 3786 if (query == &br->ip4_own_query) |
3544 br_multicast_enable(&port->ip4_own_query); | 3787 br_multicast_enable(&port->multicast_ctx.ip4_own_query); |
3545#if IS_ENABLED(CONFIG_IPV6) 3546 else | 3788#if IS_ENABLED(CONFIG_IPV6) 3789 else |
3547 br_multicast_enable(&port->ip6_own_query); | 3790 br_multicast_enable(&port->multicast_ctx.ip6_own_query); |
3548#endif 3549 } 3550 rcu_read_unlock(); 3551} 3552 3553int br_multicast_toggle(struct net_bridge *br, unsigned long val, 3554 struct netlink_ext_ack *extack) 3555{ --- 60 unchanged lines hidden (view full) --- 3616EXPORT_SYMBOL_GPL(br_multicast_enabled); 3617 3618bool br_multicast_router(const struct net_device *dev) 3619{ 3620 struct net_bridge *br = netdev_priv(dev); 3621 bool is_router; 3622 3623 spin_lock_bh(&br->multicast_lock); | 3791#endif 3792 } 3793 rcu_read_unlock(); 3794} 3795 3796int br_multicast_toggle(struct net_bridge *br, unsigned long val, 3797 struct netlink_ext_ack *extack) 3798{ --- 60 unchanged lines hidden (view full) --- 3859EXPORT_SYMBOL_GPL(br_multicast_enabled); 3860 3861bool br_multicast_router(const struct net_device *dev) 3862{ 3863 struct net_bridge *br = netdev_priv(dev); 3864 bool is_router; 3865 3866 spin_lock_bh(&br->multicast_lock); |
3624 is_router = br_multicast_is_router(br); | 3867 is_router = br_multicast_is_router(br, NULL); |
3625 spin_unlock_bh(&br->multicast_lock); 3626 return is_router; 3627} 3628EXPORT_SYMBOL_GPL(br_multicast_router); 3629 3630int br_multicast_set_querier(struct net_bridge *br, unsigned long val) 3631{ 3632 unsigned long max_delay; --- 204 unchanged lines hidden (view full) --- 3837 3838 ret = true; 3839unlock: 3840 rcu_read_unlock(); 3841 return ret; 3842} 3843EXPORT_SYMBOL_GPL(br_multicast_has_querier_adjacent); 3844 | 3868 spin_unlock_bh(&br->multicast_lock); 3869 return is_router; 3870} 3871EXPORT_SYMBOL_GPL(br_multicast_router); 3872 3873int br_multicast_set_querier(struct net_bridge *br, unsigned long val) 3874{ 3875 unsigned long max_delay; --- 204 unchanged lines hidden (view full) --- 4080 4081 ret = true; 4082unlock: 4083 rcu_read_unlock(); 4084 return ret; 4085} 4086EXPORT_SYMBOL_GPL(br_multicast_has_querier_adjacent); 4087 |
4088/** 4089 * br_multicast_has_router_adjacent - Checks for a router behind a bridge port 4090 * @dev: The bridge port adjacent to which to check for a multicast router 4091 * @proto: The protocol family to check for: IGMP -> ETH_P_IP, MLD -> ETH_P_IPV6 4092 * 4093 * Checks whether the given interface has a bridge on top and if so returns 4094 * true if a multicast router is behind one of the other ports of this 4095 * bridge. Otherwise returns false. 4096 */ 4097bool br_multicast_has_router_adjacent(struct net_device *dev, int proto) 4098{ 4099 struct net_bridge_mcast_port *pmctx; 4100 struct net_bridge_port *port; 4101 bool ret = false; 4102 4103 rcu_read_lock(); 4104 port = br_port_get_check_rcu(dev); 4105 if (!port) 4106 goto unlock; 4107 4108 switch (proto) { 4109 case ETH_P_IP: 4110 hlist_for_each_entry_rcu(pmctx, &port->br->ip4_mc_router_list, 4111 ip4_rlist) { 4112 if (pmctx->port == port) 4113 continue; 4114 4115 ret = true; 4116 goto unlock; 4117 } 4118 break; 4119#if IS_ENABLED(CONFIG_IPV6) 4120 case ETH_P_IPV6: 4121 hlist_for_each_entry_rcu(pmctx, &port->br->ip6_mc_router_list, 4122 ip6_rlist) { 4123 if (pmctx->port == port) 4124 continue; 4125 4126 ret = true; 4127 goto unlock; 4128 } 4129 break; 4130#endif 4131 default: 4132 /* when compiled without IPv6 support, be conservative and 4133 * always assume presence of an IPv6 multicast router 4134 */ 4135 ret = true; 4136 } 4137 4138unlock: 4139 rcu_read_unlock(); 4140 return ret; 4141} 4142EXPORT_SYMBOL_GPL(br_multicast_has_router_adjacent); 4143 |
|
3845static void br_mcast_stats_add(struct bridge_mcast_stats __percpu *stats, 3846 const struct sk_buff *skb, u8 type, u8 dir) 3847{ 3848 struct bridge_mcast_stats *pstats = this_cpu_ptr(stats); 3849 __be16 proto = skb->protocol; 3850 unsigned int t_len; 3851 3852 u64_stats_update_begin(&pstats->syncp); --- 171 unchanged lines hidden --- | 4144static void br_mcast_stats_add(struct bridge_mcast_stats __percpu *stats, 4145 const struct sk_buff *skb, u8 type, u8 dir) 4146{ 4147 struct bridge_mcast_stats *pstats = this_cpu_ptr(stats); 4148 __be16 proto = skb->protocol; 4149 unsigned int t_len; 4150 4151 u64_stats_update_begin(&pstats->syncp); --- 171 unchanged lines hidden --- |