[ofa-general] [PATCH] IPoIB: check multicast address format
Moni Shoua
monis at Voltaire.COM
Mon Aug 24 01:36:44 PDT 2009
Jason Gunthorpe wrote:
> Check that the format of the multicast link address is correct before
> taking it from dev->mc_list to priv->multicast_list. This way we never
> try to send a bogus address to the SA, and prevents badness from
> erronous 'ip maddr addr add', broken bonding drivers, or whatever.
>
> Signed-off-by: Jason Gunthorpe <jgunthorpe at obsidianresearch.com>
> ---
> drivers/infiniband/ulp/ipoib/ipoib_multicast.c | 18 ++++++++++++++++++
> 1 files changed, 18 insertions(+), 0 deletions(-)
>
> Same problem Moni was working on, but lets just address it directly.
>
> There is work to try and fix the bonding driver but no fixed version
> is in mainline yet. This is a cheap and simple work around that is
> worth having even once the driver is fixed.
>
> Despite this, I think it is still necessary to do something like Moni
> was trying - to prevent the MCG join queue from head of line blocking
> on a single bad SA response. This can happen even if everything is
> correct.
>
> diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> index 425e311..973a24b 100644
> --- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> +++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
> @@ -758,6 +758,20 @@ void ipoib_mcast_dev_flush(struct net_device *dev)
> }
> }
>
> +static int check_mcast(const u8 *addr,unsigned int addrlen,
> + const u8 *broadcast)
> +{
> + if (addrlen != 20)
> + return 0;
> + /* QPN, scope, reserved, sigature upper */
> + if (memcmp(addr,broadcast,6) != 0)
> + return 0;
> + /* signature lower, pkey */
> + if (memcmp(addr + 7,broadcast+7,3) != 0)
> + return 0;
> + return 1;
> +}
> +
> void ipoib_mcast_restart_task(struct work_struct *work)
> {
> struct ipoib_dev_priv *priv =
> @@ -791,6 +805,10 @@ void ipoib_mcast_restart_task(struct work_struct *work)
> for (mclist = dev->mc_list; mclist; mclist = mclist->next) {
> union ib_gid mgid;
>
> + if (!check_mcast(mclist->dmi_addr,mclist->dmi_addrlen,
> + dev->broadcast))
> + continue;
> +
> memcpy(mgid.raw, mclist->dmi_addr + 4, sizeof mgid);
>
> mcast = __ipoib_mcast_find(dev, &mgid);
Why not check validity with something that looks like the reverse operation
of the kernel function that maps ip -> link mcast addresses?
for example this is the function for IPv4
static inline void ip_ib_mc_map(__be32 naddr, const unsigned char *broadcast, char *buf)
{
__u32 addr;
unsigned char scope = broadcast[5] & 0xF;
buf[0] = 0; /* Reserved */
buf[1] = 0xff; /* Multicast QPN */
buf[2] = 0xff;
buf[3] = 0xff;
addr = ntohl(naddr);
buf[4] = 0xff;
buf[5] = 0x10 | scope; /* scope from broadcast address */
buf[6] = 0x40; /* IPv4 signature */
buf[7] = 0x1b;
buf[8] = broadcast[8]; /* P_Key */
buf[9] = broadcast[9];
buf[10] = 0;
buf[11] = 0;
buf[12] = 0;
buf[13] = 0;
buf[14] = 0;
buf[15] = 0;
buf[19] = addr & 0xff;
addr >>= 8;
buf[18] = addr & 0xff;
addr >>= 8;
buf[17] = addr & 0xff;
addr >>= 8;
buf[16] = addr & 0x0f;
}
More information about the general
mailing list