diff options
author | Jason Gunthorpe <jgunthorpe@obsidianresearch.com> | 2009-09-05 23:23:40 -0400 |
---|---|---|
committer | Roland Dreier <rolandd@cisco.com> | 2009-09-05 23:23:40 -0400 |
commit | 5e47596bee12597824a3b5b21e20f80b61e58a35 (patch) | |
tree | 10e74d0c390283e6d449d3c9b171c8c689b5be0c /drivers/infiniband | |
parent | 721d67cdca5b7642b380ca0584de8dceecf6102f (diff) |
IPoIB: Check multicast address format
Check that the format of multicast link addresses is correct before
taking them from dev->mc_list to priv->multicast_list. This way we
never try to send a bogus address to the SA, which prevents badness
from erronous 'ip maddr addr add', broken bonding drivers, etc.
Signed-off-by: Jason Gunthorpe <jgunthorpe@obsidianresearch.com>
Signed-off-by: Roland Dreier <rolandd@cisco.com>
Diffstat (limited to 'drivers/infiniband')
-rw-r--r-- | drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c index a0825fe451e0..25874fc680c9 100644 --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c | |||
@@ -760,6 +760,20 @@ void ipoib_mcast_dev_flush(struct net_device *dev) | |||
760 | } | 760 | } |
761 | } | 761 | } |
762 | 762 | ||
763 | static int ipoib_mcast_addr_is_valid(const u8 *addr, unsigned int addrlen, | ||
764 | const u8 *broadcast) | ||
765 | { | ||
766 | if (addrlen != INFINIBAND_ALEN) | ||
767 | return 0; | ||
768 | /* reserved QPN, prefix, scope */ | ||
769 | if (memcmp(addr, broadcast, 6)) | ||
770 | return 0; | ||
771 | /* signature lower, pkey */ | ||
772 | if (memcmp(addr + 7, broadcast + 7, 3)) | ||
773 | return 0; | ||
774 | return 1; | ||
775 | } | ||
776 | |||
763 | void ipoib_mcast_restart_task(struct work_struct *work) | 777 | void ipoib_mcast_restart_task(struct work_struct *work) |
764 | { | 778 | { |
765 | struct ipoib_dev_priv *priv = | 779 | struct ipoib_dev_priv *priv = |
@@ -793,6 +807,11 @@ void ipoib_mcast_restart_task(struct work_struct *work) | |||
793 | for (mclist = dev->mc_list; mclist; mclist = mclist->next) { | 807 | for (mclist = dev->mc_list; mclist; mclist = mclist->next) { |
794 | union ib_gid mgid; | 808 | union ib_gid mgid; |
795 | 809 | ||
810 | if (!ipoib_mcast_addr_is_valid(mclist->dmi_addr, | ||
811 | mclist->dmi_addrlen, | ||
812 | dev->broadcast)) | ||
813 | continue; | ||
814 | |||
796 | memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid); | 815 | memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid); |
797 | 816 | ||
798 | mcast = __ipoib_mcast_find(dev, &mgid); | 817 | mcast = __ipoib_mcast_find(dev, &mgid); |