[ewg] [PATCHv8 10/11] ib_core: Add VLAN support to IBoE
Add 802.1q vlan support to IBoE. The vlan tag is encoded within the GID derived from a link local address in the following way: GID[11] GID[12] contain the vlan ID. The 3 bit user priority field is identical to the 3 bits of the SL. In case rdma_cm apps, the TOS field is used to generate the SL field by doing a shift right of 5 bits effectively taking to 3 MS bits of the TOS field. In order to support userspace verbs consumers, ib_uverbs_get_mac has changed into ib_uverbs_get_eth_l2_addr and now returns both MAC and VLAN information. Signed-off-by: Eli Cohen --- drivers/infiniband/core/cma.c | 20 - drivers/infiniband/core/ucma.c | 13 - drivers/infiniband/core/ud_header.c | 31 - include/rdma/ib_addr.h | 49 --- include/rdma/ib_pack.h | 19 ++--- 5 files changed, 106 insertions(+), 26 deletions(-) diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c index df5f636..108d1bb 100644 --- a/drivers/infiniband/core/cma.c +++ b/drivers/infiniband/core/cma.c @@ -1763,6 +1763,7 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) struct sockaddr_in *src_addr = (struct sockaddr_in *)&route->addr.src_addr; struct sockaddr_in *dst_addr = (struct sockaddr_in *)&route->addr.dst_addr; struct net_device *ndev = NULL; + u16 vid; if (src_addr->sin_family != dst_addr->sin_family) return -EINVAL; @@ -1782,14 +1783,6 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) route->num_paths = 1; - iboe_mac_to_ll(&route->path_rec->sgid, addr->dev_addr.src_dev_addr); - iboe_mac_to_ll(&route->path_rec->dgid, addr->dev_addr.dst_dev_addr); - - route->path_rec->hop_limit = 1; - route->path_rec->reversible = 1; - route->path_rec->pkey = cpu_to_be16(0x); - route->path_rec->mtu_selector = IB_SA_EQ; - if (addr->dev_addr.bound_dev_if) ndev = dev_get_by_index(&init_net, addr->dev_addr.bound_dev_if); if (!ndev) { @@ -1797,6 +1790,17 @@ static int cma_resolve_iboe_route(struct rdma_id_private *id_priv) goto err2; } + vid = rdma_vlan_dev_vlan_id(ndev); + + iboe_mac_vlan_to_ll(&route->path_rec->sgid, addr->dev_addr.src_dev_addr, vid); + iboe_mac_vlan_to_ll(&route->path_rec->dgid, addr->dev_addr.dst_dev_addr, vid); + + route->path_rec->hop_limit = 1; + route->path_rec->reversible = 1; + route->path_rec->pkey = cpu_to_be16(0x); + route->path_rec->mtu_selector = IB_SA_EQ; + route->path_rec->sl = id_priv->tos >> 5; + route->path_rec->mtu = iboe_get_mtu(ndev->mtu); route->path_rec->rate_selector = IB_SA_EQ; route->path_rec->rate = iboe_get_rate(ndev); diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c index fcc27bc..ed670f5 100644 --- a/drivers/infiniband/core/ucma.c +++ b/drivers/infiniband/core/ucma.c @@ -586,13 +586,22 @@ static void ucma_copy_iboe_route(struct rdma_ucm_query_route_resp *resp, struct rdma_route *route) { struct rdma_dev_addr *dev_addr; + struct net_device *dev; + u16 vid = 0; resp->num_paths = route->num_paths; switch (route->num_paths) { case 0: dev_addr = &route->addr.dev_addr; - iboe_mac_to_ll((union ib_gid *) &resp->ib_route[0].dgid, - dev_addr->dst_dev_addr); + dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); + if (dev) { + vid = rdma_vlan_dev_vlan_id(dev); + dev_put(dev); + } + + + iboe_mac_vlan_to_ll((union ib_gid *) &resp->ib_route[0].dgid, + dev_addr->dst_dev_addr, vid); iboe_addr_get_sgid(dev_addr, (union ib_gid *) &resp->ib_route[0].sgid); resp->ib_route[0].pkey = cpu_to_be16(0x); diff --git a/drivers/infiniband/core/ud_header.c b/drivers/infiniband/core/ud_header.c index 7650313..7d03cf1 100644 --- a/drivers/infiniband/core/ud_header.c +++ b/drivers/infiniband/core/ud_header.c @@ -33,6 +33,7 @@ #include #include +#include #include @@ -103,6 +104,17 @@ static const struct ib_field eth_table[] = { .size_bits= 16 } }; +static const struct ib_field vlan_table[] = { + { STRUCT_FIELD(vlan, tag), + .offset_words = 0, + .offset_bits = 0, + .size_bits= 16 }, + { STRUCT_FIELD(vlan, type), + .offset_words = 0, + .offset_bits = 16, + .size_bits= 16 } +}; + static const struct ib_field grh_table[] = { { STRUCT_FIELD(grh, ip_version), .offset_words = 0, @@ -205,6 +217,7 @@ static
Re: [ewg] [PATCHv8 10/11] ib_core: Add VLAN support to IBoE
Eli, I'm getting build failure of our kernel module with OFED-1.5.2-rc1. /usr/src/ofa_kernel/include/rdma/ib_addr.h: In function ‘iboe_addr_get_sgid’: /usr/src/ofa_kernel/include/rdma/ib_addr.h:160: error: implicit declaration of function ‘vlan_dev_vlan_id’ I'm using a standard Redhat EL 5.3 setup. kernel is 2.6.18-128.7.1.el5 include/linux/autoconf.h has the following defined but the function doesn't seem to be defined in the kernel. CONFIG_VLAN_8021Q_MODULE 1 I can work around the problem by hacking /usr/src/ofa_kernel/include/rdma/ib_addr.h with undefining the VLAN stuff. #undef CONFIG_VLAN_8021Q #undef CONFIG_VLAN_8021Q_MODULE Any ideas to fix this in a graceful way? On Thu, Feb 18, 2010 at 10:24 AM, Eli Cohen wrote: > Add 802.1q vlan support to IBoE. The vlan tag is encoded within the GID > derived from a link local address in the following way: > > GID[11] GID[12] contain the vlan ID. > The 3 bit user priority field is identical to the 3 bits of the SL. > > In case rdma_cm apps, the TOS field is used to generate the SL field by > doing a > shift right of 5 bits effectively taking to 3 MS bits of the TOS field. In > order to support userspace verbs consumers, ib_uverbs_get_mac has changed > into > ib_uverbs_get_eth_l2_addr and now returns both MAC and VLAN information. > > Signed-off-by: Eli Cohen > --- > drivers/infiniband/core/cma.c | 20 - > drivers/infiniband/core/ucma.c | 13 - > drivers/infiniband/core/ud_header.c | 31 - > include/rdma/ib_addr.h | 49 > --- > include/rdma/ib_pack.h | 19 ++--- > 5 files changed, 106 insertions(+), 26 deletions(-) > > diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c > index df5f636..108d1bb 100644 > --- a/drivers/infiniband/core/cma.c > +++ b/drivers/infiniband/core/cma.c > @@ -1763,6 +1763,7 @@ static int cma_resolve_iboe_route(struct > rdma_id_private *id_priv) >struct sockaddr_in *src_addr = (struct sockaddr_in > *)&route->addr.src_addr; >struct sockaddr_in *dst_addr = (struct sockaddr_in > *)&route->addr.dst_addr; >struct net_device *ndev = NULL; > + u16 vid; > >if (src_addr->sin_family != dst_addr->sin_family) >return -EINVAL; > @@ -1782,14 +1783,6 @@ static int cma_resolve_iboe_route(struct > rdma_id_private *id_priv) > >route->num_paths = 1; > > - iboe_mac_to_ll(&route->path_rec->sgid, > addr->dev_addr.src_dev_addr); > - iboe_mac_to_ll(&route->path_rec->dgid, > addr->dev_addr.dst_dev_addr); > - > - route->path_rec->hop_limit = 1; > - route->path_rec->reversible = 1; > - route->path_rec->pkey = cpu_to_be16(0x); > - route->path_rec->mtu_selector = IB_SA_EQ; > - >if (addr->dev_addr.bound_dev_if) >ndev = dev_get_by_index(&init_net, > addr->dev_addr.bound_dev_if); >if (!ndev) { > @@ -1797,6 +1790,17 @@ static int cma_resolve_iboe_route(struct > rdma_id_private *id_priv) >goto err2; >} > > + vid = rdma_vlan_dev_vlan_id(ndev); > + > + iboe_mac_vlan_to_ll(&route->path_rec->sgid, > addr->dev_addr.src_dev_addr, vid); > + iboe_mac_vlan_to_ll(&route->path_rec->dgid, > addr->dev_addr.dst_dev_addr, vid); > + > + route->path_rec->hop_limit = 1; > + route->path_rec->reversible = 1; > + route->path_rec->pkey = cpu_to_be16(0x); > + route->path_rec->mtu_selector = IB_SA_EQ; > + route->path_rec->sl = id_priv->tos >> 5; > + >route->path_rec->mtu = iboe_get_mtu(ndev->mtu); >route->path_rec->rate_selector = IB_SA_EQ; >route->path_rec->rate = iboe_get_rate(ndev); > diff --git a/drivers/infiniband/core/ucma.c > b/drivers/infiniband/core/ucma.c > index fcc27bc..ed670f5 100644 > --- a/drivers/infiniband/core/ucma.c > +++ b/drivers/infiniband/core/ucma.c > @@ -586,13 +586,22 @@ static void ucma_copy_iboe_route(struct > rdma_ucm_query_route_resp *resp, > struct rdma_route *route) > { >struct rdma_dev_addr *dev_addr; > + struct net_device *dev; > + u16 vid = 0; > >resp->num_paths = route->num_paths; >switch (route->num_paths) { >case 0: >dev_addr = &route->addr.dev_addr; > - iboe_mac_to_ll((union ib_gid *) &resp->ib_route[0].dgid, > - dev_addr->dst_dev_addr); > + dev = dev_get_by_index(&init_net, dev_addr->bound_dev_if); > + if (dev) { > + vid = rdma_vlan_dev_vlan_id(dev); > + dev_put(dev); > + } > + > + > + iboe_mac_vlan_to_ll((union ib_gid *) > &resp->ib_route[0].dgid, > + dev_addr->dst_dev_addr, vid); >iboe_addr_get_sgid(dev_addr, > (union ib_g