Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

net/ncsi: Disable global multicast filter

Disabling multicast filtering from NCSI if it is supported. As it
should not filter any multicast packets. In current code, multicast
filter is enabled and with an exception of optional field supported
by device are disabled filtering.

Mainly I see if goal is to disable filtering for IPV6 packets then let
it disabled for every other types as well. As we are seeing issues with
LLDP not working with this enabled filtering. And there are other issues
with IPV6.

By Disabling this multicast completely, it is working for both IPV6 as
well as LLDP.

Signed-off-by: Vijay Khemka <vijaykhemka@fb.com>
Acked-by: Samuel Mendoza-Jonas <sam@mendozajonas.com>
Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>

authored by

Vijay Khemka and committed by
Jakub Kicinski
cf0eba33 dd0f9d89

+15 -96
+1 -6
net/ncsi/internal.h
··· 264 264 ncsi_dev_state_config_ev, 265 265 ncsi_dev_state_config_sma, 266 266 ncsi_dev_state_config_ebf, 267 - #if IS_ENABLED(CONFIG_IPV6) 268 - ncsi_dev_state_config_egmf, 269 - #endif 267 + ncsi_dev_state_config_dgmf, 270 268 ncsi_dev_state_config_ecnt, 271 269 ncsi_dev_state_config_ec, 272 270 ncsi_dev_state_config_ae, ··· 293 295 #define NCSI_DEV_RESET 8 /* Reset state of NC */ 294 296 unsigned int gma_flag; /* OEM GMA flag */ 295 297 spinlock_t lock; /* Protect the NCSI device */ 296 - #if IS_ENABLED(CONFIG_IPV6) 297 - unsigned int inet6_addr_num; /* Number of IPv6 addresses */ 298 - #endif 299 298 unsigned int package_probe_id;/* Current ID during probe */ 300 299 unsigned int package_num; /* Number of packages */ 301 300 struct list_head packages; /* List of packages */
+14 -90
net/ncsi/ncsi-manage.c
··· 14 14 #include <net/sock.h> 15 15 #include <net/addrconf.h> 16 16 #include <net/ipv6.h> 17 - #include <net/if_inet6.h> 18 17 #include <net/genetlink.h> 19 18 20 19 #include "internal.h" ··· 977 978 case ncsi_dev_state_config_ev: 978 979 case ncsi_dev_state_config_sma: 979 980 case ncsi_dev_state_config_ebf: 980 - #if IS_ENABLED(CONFIG_IPV6) 981 - case ncsi_dev_state_config_egmf: 982 - #endif 981 + case ncsi_dev_state_config_dgmf: 983 982 case ncsi_dev_state_config_ecnt: 984 983 case ncsi_dev_state_config_ec: 985 984 case ncsi_dev_state_config_ae: ··· 1030 1033 } else if (nd->state == ncsi_dev_state_config_ebf) { 1031 1034 nca.type = NCSI_PKT_CMD_EBF; 1032 1035 nca.dwords[0] = nc->caps[NCSI_CAP_BC].cap; 1036 + /* if multicast global filtering is supported then 1037 + * disable it so that all multicast packet will be 1038 + * forwarded to management controller 1039 + */ 1040 + if (nc->caps[NCSI_CAP_GENERIC].cap & 1041 + NCSI_CAP_GENERIC_MC) 1042 + nd->state = ncsi_dev_state_config_dgmf; 1043 + else if (ncsi_channel_is_tx(ndp, nc)) 1044 + nd->state = ncsi_dev_state_config_ecnt; 1045 + else 1046 + nd->state = ncsi_dev_state_config_ec; 1047 + } else if (nd->state == ncsi_dev_state_config_dgmf) { 1048 + nca.type = NCSI_PKT_CMD_DGMF; 1033 1049 if (ncsi_channel_is_tx(ndp, nc)) 1034 1050 nd->state = ncsi_dev_state_config_ecnt; 1035 1051 else 1036 1052 nd->state = ncsi_dev_state_config_ec; 1037 - #if IS_ENABLED(CONFIG_IPV6) 1038 - if (ndp->inet6_addr_num > 0 && 1039 - (nc->caps[NCSI_CAP_GENERIC].cap & 1040 - NCSI_CAP_GENERIC_MC)) 1041 - nd->state = ncsi_dev_state_config_egmf; 1042 - } else if (nd->state == ncsi_dev_state_config_egmf) { 1043 - nca.type = NCSI_PKT_CMD_EGMF; 1044 - nca.dwords[0] = nc->caps[NCSI_CAP_MC].cap; 1045 - if (ncsi_channel_is_tx(ndp, nc)) 1046 - nd->state = ncsi_dev_state_config_ecnt; 1047 - else 1048 - nd->state = ncsi_dev_state_config_ec; 1049 - #endif /* CONFIG_IPV6 */ 1050 1053 } else if (nd->state == ncsi_dev_state_config_ecnt) { 1051 1054 if (np->preferred_channel && 1052 1055 nc != np->preferred_channel) ··· 1480 1483 return -ENODEV; 1481 1484 } 1482 1485 1483 - #if IS_ENABLED(CONFIG_IPV6) 1484 - static int ncsi_inet6addr_event(struct notifier_block *this, 1485 - unsigned long event, void *data) 1486 - { 1487 - struct inet6_ifaddr *ifa = data; 1488 - struct net_device *dev = ifa->idev->dev; 1489 - struct ncsi_dev *nd = ncsi_find_dev(dev); 1490 - struct ncsi_dev_priv *ndp = nd ? TO_NCSI_DEV_PRIV(nd) : NULL; 1491 - struct ncsi_package *np; 1492 - struct ncsi_channel *nc; 1493 - struct ncsi_cmd_arg nca; 1494 - bool action; 1495 - int ret; 1496 - 1497 - if (!ndp || (ipv6_addr_type(&ifa->addr) & 1498 - (IPV6_ADDR_LINKLOCAL | IPV6_ADDR_LOOPBACK))) 1499 - return NOTIFY_OK; 1500 - 1501 - switch (event) { 1502 - case NETDEV_UP: 1503 - action = (++ndp->inet6_addr_num) == 1; 1504 - nca.type = NCSI_PKT_CMD_EGMF; 1505 - break; 1506 - case NETDEV_DOWN: 1507 - action = (--ndp->inet6_addr_num == 0); 1508 - nca.type = NCSI_PKT_CMD_DGMF; 1509 - break; 1510 - default: 1511 - return NOTIFY_OK; 1512 - } 1513 - 1514 - /* We might not have active channel or packages. The IPv6 1515 - * required multicast will be enabled when active channel 1516 - * or packages are chosen. 1517 - */ 1518 - np = ndp->active_package; 1519 - nc = ndp->active_channel; 1520 - if (!action || !np || !nc) 1521 - return NOTIFY_OK; 1522 - 1523 - /* We needn't enable or disable it if the function isn't supported */ 1524 - if (!(nc->caps[NCSI_CAP_GENERIC].cap & NCSI_CAP_GENERIC_MC)) 1525 - return NOTIFY_OK; 1526 - 1527 - nca.ndp = ndp; 1528 - nca.req_flags = 0; 1529 - nca.package = np->id; 1530 - nca.channel = nc->id; 1531 - nca.dwords[0] = nc->caps[NCSI_CAP_MC].cap; 1532 - ret = ncsi_xmit_cmd(&nca); 1533 - if (ret) { 1534 - netdev_warn(dev, "Fail to %s global multicast filter (%d)\n", 1535 - (event == NETDEV_UP) ? "enable" : "disable", ret); 1536 - return NOTIFY_DONE; 1537 - } 1538 - 1539 - return NOTIFY_OK; 1540 - } 1541 - 1542 - static struct notifier_block ncsi_inet6addr_notifier = { 1543 - .notifier_call = ncsi_inet6addr_event, 1544 - }; 1545 - #endif /* CONFIG_IPV6 */ 1546 - 1547 1486 static int ncsi_kick_channels(struct ncsi_dev_priv *ndp) 1548 1487 { 1549 1488 struct ncsi_dev *nd = &ndp->ndev; ··· 1658 1725 } 1659 1726 1660 1727 spin_lock_irqsave(&ncsi_dev_lock, flags); 1661 - #if IS_ENABLED(CONFIG_IPV6) 1662 - ndp->inet6_addr_num = 0; 1663 - if (list_empty(&ncsi_dev_list)) 1664 - register_inet6addr_notifier(&ncsi_inet6addr_notifier); 1665 - #endif 1666 1728 list_add_tail_rcu(&ndp->node, &ncsi_dev_list); 1667 1729 spin_unlock_irqrestore(&ncsi_dev_lock, flags); 1668 1730 ··· 1824 1896 1825 1897 spin_lock_irqsave(&ncsi_dev_lock, flags); 1826 1898 list_del_rcu(&ndp->node); 1827 - #if IS_ENABLED(CONFIG_IPV6) 1828 - if (list_empty(&ncsi_dev_list)) 1829 - unregister_inet6addr_notifier(&ncsi_inet6addr_notifier); 1830 - #endif 1831 1899 spin_unlock_irqrestore(&ncsi_dev_lock, flags); 1832 1900 1833 1901 ncsi_unregister_netlink(nd->dev);